Sujet : Re: how to make a macro work as a single line if stmt without braces
De : Keith.S.Thompson+u (at) *nospam* gmail.com (Keith Thompson)
Groupes : comp.lang.cDate : 21. Sep 2024, 22:44:26
Autres entêtes
Organisation : None to speak of
Message-ID : <87jzf4r8at.fsf@nosuchdomain.example.com>
References : 1 2
User-Agent : Gnus/5.13 (Gnus v5.13)
Ike Naar <
ike@sdf.org> writes:
On 2024-09-21, Mark Summerfield <mark@qtrac.eu> wrote:
I have this macro:
>
#define WARN(...) \
do { \
fprintf(stderr, "%s#%d: ", __FILE__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
} while (0);
>
[...]
>
I would prefer to be able to write this instead:
>
total++;
if (failed)
WARN("failed because...");
else
ok++;
>
but doing so results in a compiler error:
>
error: 'else' without a previous 'if'
>
After expansion of the WARN macro there are two semicolons before the 'else'.
The first semicolon is from the
>
} while (0);
>
line, the second is from the
>
WARN("failed because...");
>
line.
Removing the semicolon from one of these two lines fixes the compiler error.
And removing the semicolon from the macro definition is the only
sensible way to do this.
The do ... while (condition) idiom is the conventional way to write a
macro that can be used in any context that requires a statement. Adding
the semicolon in the macro definition and expecting users to omit the
semicolon when invoking it is not a good idea.
See question 10.4 of the comp.lang.c FAQ, <
https://www.c-faq.com/>.
-- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.comvoid Void(void) { Void(); } /* The recursive call of the void */