Bug 53182

Summary: GNU C: attributes without underscores should be discouraged / no longer be documented e.g. as examples
Product: gcc Reporter: Vincent Lefèvre <vincent-gcc>
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: enhancement CC: ericb, sandra
Priority: P3 Keywords: documentation
Version: unknown   
Target Milestone: ---   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102397
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88472
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2012-05-02 00:00:00

Description Vincent Lefèvre 2012-05-02 01:39:44 UTC
Attributes without underscores can conflict with the ISO C standard. For instance, if the C11 <stdnoreturn.h> header is included, this breaks GCC's

  __attribute__ ((noreturn))

(such problems may occur in particular if different libraries, with different expectations, are used). To avoid such a clash, only the __noreturn__ version should be used. Other attributes without __ may also lead to conflicts with a future C standard. You can see

  http://lists.gnu.org/archive/html/bug-gnulib/2012-05/msg00024.html

and the corresponding discussion, from which I've reported this bug.

I suggest the following changes:

* Fix the GCC manual: the versions without __ should be discouraged (explain why) and the examples should always use the __ version, e.g. change

          void fatal () __attribute__ ((noreturn));

to

          void fatal () __attribute__ ((__noreturn__));

* Possibly issue a warning if an attribute without __ is used.
Comment 1 Richard Biener 2012-05-02 11:54:02 UTC
Confirmed.
Comment 2 Eric Blake 2012-05-02 13:27:28 UTC
It would also help to add an attribute named __attribute__((_Noreturn)) (and therefore also adding __attribute__((___Noreturn__)), of course), for this particular instance of <stdnoreturn.h> vs. existing code.
Comment 3 sandra 2018-11-22 01:47:06 UTC
On this issue I'd like to get agreement from a broader community that it is a good idea to deprecate the non-underscore names before implementing the documentation changes.  I also think there are other compilers that have copied the GCC attribute syntax; do they also recognize both the underscore and non-underscore name variants?

The edits for this would be fairly mechanical, but I'm concerned that it won't help readability of the manual, and would be confusing to people who have some existing code with some attributes not using the __foo__ convention that they want to look up.  At the very least we'd want to index both names.  

Also the optional underscore naming is currently explained in the attribute syntax section, which appears after the sections where all the different flavors of attributes are listed.  That would need to be moved to a more prominent location.
Comment 4 Jonathan Wakely 2018-11-22 09:31:33 UTC
(In reply to sandra from comment #3)
> I also think there are other compilers that have
> copied the GCC attribute syntax; do they also recognize both the underscore
> and non-underscore name variants?

Yes (confirmed for Clang and Intel, I don't know about others).
Comment 5 Jonathan Wakely 2018-11-22 09:39:40 UTC
(In reply to Vincent Lefèvre from comment #0)
> Attributes without underscores can conflict with the ISO C standard. For
> instance, if the C11 <stdnoreturn.h> header is included, this breaks GCC's
> 
>   __attribute__ ((noreturn))
> 
> (such problems may occur in particular if different libraries, with
> different expectations, are used). To avoid such a clash, only the
> __noreturn__ version should be used. Other attributes without __ may also
> lead to conflicts with a future C standard.

But *any* identifier can conflict with a macro from a future C standard. Why are these attributes special?

I understand that there's a specific conflict for __attribute__((noreturn)) and <stdnoreturn.h> but I don't see why that implies all other attribute names have problems that are significantly worse than for any other identifier.
Comment 6 Vincent Lefèvre 2018-11-22 13:00:33 UTC
(In reply to Jonathan Wakely from comment #5)
> But *any* identifier can conflict with a macro from a future C standard. Why
> are these attributes special?
> 
> I understand that there's a specific conflict for __attribute__((noreturn))
> and <stdnoreturn.h> but I don't see why that implies all other attribute
> names have problems that are significantly worse than for any other
> identifier.

This comes from "That would be a bug in the other package for using noreturn instead of __noreturn__, and should be fixable." at http://lists.gnu.org/archive/html/bug-gnulib/2012-05/msg00024.html but I don't know on what this is based.

This is not specific to noreturn, because in C99, it didn't exist yet (I mean that in future C standards, you could have similar problems with other attributes).

Also, note that identifiers that are not reserved should not be used, because they could be defined as macros by the developer, who has not tested his code with GCC (I'm saying GCC here, but this applies to any compiler).
Comment 7 Jonathan Wakely 2018-11-22 14:18:17 UTC
(In reply to Vincent Lefèvre from comment #6)
> This is not specific to noreturn, because in C99, it didn't exist yet (I
> mean that in future C standards, you could have similar problems with other
> attributes).

And with any identifier.

> Also, note that identifiers that are not reserved should not be used,
> because they could be defined as macros by the developer, who has not tested
> his code with GCC (I'm saying GCC here, but this applies to any compiler).

Should not be used by who? For what purposes? In which contexts?

Users have to use non-reserved identifiers for their own code. A standard library implementation needs to use the __noreturn__ form, but standard library developers know that (well, except the darwin libc devs, PR 64883) and the GCC manual is not aimed at them.

I think the specific case of noreturn could be addressed in the docs like so:

--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3233,6 +3233,10 @@ restored before calling the @code{noreturn} function.
 It does not make sense for a @code{noreturn} function to have a return
 type other than @code{void}.
 
+The C11 standard defines @code{noreturn} as a macro, in the header
+@code{<stdnoreturn.h>}, so to avoid conflicting with that macro, the
+reserved name form of the attribute can be used, @code{__noreturn__}.
+
 @item nothrow
 @cindex @code{nothrow} function attribute
 The @code{nothrow} attribute is used to inform the compiler that a


Eric's suggestion in comment 2 makes sense too, so that __attribute__((noreturn)) still works even if the macro is defined and it gets replaced with __attribute__((_Noreturn)).
Comment 8 Vincent Lefèvre 2020-02-25 15:32:17 UTC
(In reply to Jonathan Wakely from comment #7)
> (In reply to Vincent Lefèvre from comment #6)
> > Also, note that identifiers that are not reserved should not be used,
> > because they could be defined as macros by the developer, who has not tested
> > his code with GCC (I'm saying GCC here, but this applies to any compiler).
> 
> Should not be used by who?

by non-user code, but this applies in particular to what's inside __attribute__.

Here's an example. In MPFR's mpfr.h file, we use:

#define __MPFR_SENTINEL_ATTR
#if defined (__GNUC__)
# if __GNUC__ >= 4
#  undef __MPFR_SENTINEL_ATTR
#  define __MPFR_SENTINEL_ATTR __attribute__ ((sentinel))
# endif
#endif

But if in my personal C code, I have

#define sentinel 1

before the #include's or, in a similar way, compile my program with -Dsentinel, then I get a compilation failure. Here the end user is not supposed to know that the identifier "sentinel" (which is not reserved) is used internally.