Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add more _noreturn_ attributes as suggested my -Wsuggest-attribute=noreturn #223

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

DerDakon
Copy link
Member

Since we have that attribute available anyway we can as well add it to more functions to allow the compiler to generate better code.

@leahneukirchen
Copy link
Contributor

I think this is overkill, as you can see here, even with -O1 the noreturn of exit is propagated the the function that definitively calls it: https://godbolt.org/z/G1ed7vfxe
Thus, annotating strerr_die in strerr.h should yield the same code benefits.
(Furthermore, _noreturn_ clashes with the globally reserved identifiers, we should import <stdnoreturn.h> (C11) when possible and define noreturn to be empty else; I must have missed that on the previous PR.)

@mbhangui
Copy link
Contributor

one can use STDC_VERSION in noreturn.h

https://stackoverflow.com/questions/28552467/is-there-a-way-to-use-gcc-attribute-noreturn-and-stdnoreturn-h-sanely-i

There is the suggestion to use __attribute__((__noreturn__)) instead of __attribute__((noreturn)) and also using STDC_VERSION to avoid problems with including <stdnoreturn.h>

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define noreturn _Noreturn
#elif defined(__GNUC__)
#define noreturn __attribute__((noreturn))
#else
#define noreturn
#endif

@DerDakon
Copy link
Member Author

I wonder if we should not just use _Noreturn and add compatibility defines for that if it is not present.

@leahneukirchen
Copy link
Contributor

But why? If you define a macro anyway, just call it like the official C11 name.

@DerDakon
Copy link
Member Author

It's unclear to me what is the official name, if it is the define that comes from the header or the internal keyword. The plan is of course to use the standard one.

This specifier is typically used through the convenience macro noreturn, which is provided in the header stdnoreturn.h
CppReference.com

This suggests that the noreturn define is not the real defined thing.

@leahneukirchen
Copy link
Contributor

The C11 keyword is _Noreturn, because for backwards compatibility they can't add new keywords with lowercase. But C11 also specifies the header <stdnoreturn.h> (7.23) which defines noreturn and doesn't want you make gouge your eyes out.

@mbhangui
Copy link
Contributor

mbhangui commented Aug 30, 2021

including stdnoreturn.h breaks gcc if you use _attribute_ ((noreturn)). I had this problem last year compiling ezmlm-idx. ezmlm-idx uses this macro in die.h and cgi.h. I managed to find what the issue is. Here are two examples. The first example ignores noreturn because of stdnoreturn.h. Without stdnoreturn.h, it does the job. The second examples does the required job of adding noreturn attribute even with stdnoreturn.h included. The bug is mentioned here.
I faced this problem with gcc on fc33 and now on fc34 too (gcc version 11.2.1 20210728 (Red Hat 11.2.1-1) (GCC)).

** Example1 problem with including stdnoreturn.h

# cat a1.c
#include <unistd.h>
#include <stdnoreturn.h>
#define _noreturn_ __attribute__((noreturn))

__attribute__ ((__noreturn__)) void foo1()
{
        _exit(1);
}

_noreturn_ void foo2()
{
        _exit(1);
}
# gcc -Wsuggest-attribute=noreturn -c a1.c
a1.c:11:1: warning: ‘_Noreturn’ attribute directive ignored [-Wattributes]
   11 | {
      | ^
a1.c: In function ‘foo2’:
a1.c:10:17: warning: function might be candidate for attribute ‘noreturn’ [-Wsuggest-attribute=noreturn]
   10 | _noreturn_ void foo2()
      |                 ^~~~

Workaround is to use attribute ((noreturn)) instead of attribute ((noreturn))

** Example2

# cat a2.c
#include <unistd.h>
#include <stdnoreturn.h>
#define _noreturn_ __attribute__((__noreturn__))

__attribute__ ((__noreturn__)) void foo1()
{
        _exit(1);
}

_noreturn_ void foo2()
{
        _exit(1);
}
# gcc -Wsuggest-attribute=noreturn -c a2.c

@DerDakon
Copy link
Member Author

What works should be something like this:

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#include <stdnoreturn.h>
#elif defined(__GNUC__)
#define noreturn __attribute__((__noreturn__))
#else
#define noreturn
#endif

…return

Since we have that attribute available anyway we can as well add it to more
functions to allow the compiler to generate better code.
@josuah
Copy link

josuah commented May 9, 2022

I felt that converting _noreturn_ to noreturn, would go the same direction as converting str_len to strlen.

Copy link

@josuah josuah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is anything happening about "noreturn" vs "noreturn", it would go in a separate commit?

All good with the () to (void) conversion as well.

@DerDakon
Copy link
Member Author

If we generally agree to just call it noreturn then I'll just change the thing, no problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants