Glenn Morris <
rgm@gnu.org> schrieb am Mo., 12. Juni 2017 um 23:46 Uhr:
Philipp Stephani wrote:
>> +#ifdef __has_attribute
>> +#if __has_attribute(__nonnull__)
>> # define EMACS_ATTRIBUTE_NONNULL(...)
>> __attribute__((__nonnull__(__VA_ARGS__)))
>> -#else
>> +#endif
>> +#endif
>> +#ifndef EMACS_ATTRIBUTE_NONNULL
>> # define EMACS_ATTRIBUTE_NONNULL(...)
>> #endif
Applied as 69899d4.
Thanks!
> Probably yes, thanks. (I don't know why the && _expression_ doesn't work.)
I could not find a good reference, but see eg
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36453#c3
I've looked it up in the (C++) standard, and the explanation makes sense. What happens is that the preprocessor first replaces the 'define' forms and expands macros, then replaces all leftover identifiers (including C keywords) with 0. So
#if defined __has_attribute && __has_attribute ((__nonnull__))
first gets translated to
#if 0 && 0 ((0))
which is then evaluated, but it's a syntax error, which fails even if the LHS of && is false.