On Wed, 5 Jan 2022 02:24:01 +0600
NRK <[email protected]> wrote:
Dear NRK,
> Answering my own question: because it fails if `__has_builtin` is not
> defined. I was expecting the 2nd expression wouldn't get evaluated at
> all. Should probably take some time and learn more about the
> pre-processor sometimes.
yes exactly. If you use normal non-function-like-macros that don't
exist, it works out, as they are simply replaced with 0 in such an
expression. At least GCC, from what I know of, always evaluates all
macros in each expression, and it seems to be undefined in the standard
if you do that beforehand.
It's different for function-like-macros: If they do not exist, it
throws an error instead of replacing it with 0, which can easily be
confirmed by trying to compile a file test.c containing
#if defined (idontexist) && idontexist(test)
#endif
yielding
$ cc -o test test.c
test.c:1:29: error: function-like macro 'idontexist' is not defined
#if defined (idontexist) && idontexist(test)
^
1 error generated.
$
This is also probably a good reason to always use nested ifdefs instead
of ifs, as using if-constructs leads to such surprises given the
macro-logic-operators don't seem to behave like the ones in the
language itself. Using ifdef forces you to only evaluate one condition
per line.
With best regards
Laslo