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.