Reputation: 48068
This is a silly problem with macro declarations, but one I've run into a few times and was curious if there is some solution I'm missing.
I have a macro that declares variables, which I want to ensure are not initialized by mistake.
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 0
Example use:
DECLARE_FOO(var);
however this allows...
DECLARE_FOO(var) + 1;
I could just ignore this (for now Im just leaving it this way), but I'd like to disallow it. simple...
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 0;
However now I have to remove the semicolon from the declaration otherwise I get this warning.
DECLARE_FOO(var);
int bar;
ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
So, I have to do this...
DECLARE_FOO(var)
int bar;
...which expands correctly, but looks odd for anyone reading the code and not checking the macro definition. Also editors that don't expand macros may warn about this as incorrect syntax.
Is there some way to disallow assignments to the variable but also end usage of the declaration with a semicolon ?
It wasn't really clear in my question, but -Werror=declaration-after-statement
infers that C90 is a requirement here, answers mixing in statements wont work in this case since there may be proceeding declarations.
Upvotes: 2
Views: 830
Reputation: 48068
As long as mixing decelerations and statements is not allowed (C90), then it is not possible to guard against trailing text after the macro.
However it is possible to use ternary operator to ignore the trailing text, this is a fairly poor solution (and I wouldn't recommend its use).
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 1 ? 0 : 0
This won't raise an error, but the + 1
will be ignored.
DECLARE_FOO(var) + 1;
Upvotes: 0
Reputation: 44250
Add a no-op expression to the macro:
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 0; \
(void) 0
BTW: this will even fail if the macro is used without a semicolon.
UPDATE: another trick: make the last line of the macro an external declaration (which also is a no-op, but will choke without a semicolon)
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 0; \
extern int _##var##_ext
Upvotes: 4