#include <stdio.h>
#define PRINT(x) (printf("%d\n", x), x)
int main() {
int a = 1;
switch (a) {
case PRINT(1): puts("Case 1"); break;
case PRINT(2): puts("Case 2"); break;
default: puts("Default");
}
}
After building the code, I'm getting the error as:
error: case label does not reduce to an integer constant
Why does the PRINT
macro fail in the switch
statement, and how can I fix it?
#include <stdio.h>
#define PRINT(x) (printf("%d\n", x), x)
int main() {
int a = 1;
switch (a) {
case PRINT(1): puts("Case 1"); break;
case PRINT(2): puts("Case 2"); break;
default: puts("Default");
}
}
After building the code, I'm getting the error as:
error: case label does not reduce to an integer constant
Why does the PRINT
macro fail in the switch
statement, and how can I fix it?
- You are not running your code, if compilation fails. – Gerhardh Commented Mar 17 at 7:42
- 2 Your comma expression is not a constant expression and so it cannot be a label in a switch statement. As for fixing it - the macro seems rather convoluted - what are you actually trying to achieve ? – wohlstad Commented Mar 17 at 7:45
3 Answers
Reset to default 6case
needs an integer constant expression, hence the self-explaining compiler error. (clang gives an even clearer one: "error: expression is not an integer constant expression")
printf("%d\n", x), x
is not and integer constant expression - it contains variable evaluations and even a function call. You will have to move the printing outside the case :
.
The argument for case
must be a compile-time integer constant expression which (printf("%d\n", x), x)
is not as the compiler says.
About how to fix it: generally, it is not recommendable to hide basic programming constructs inside macros, so I would recommend keeping the case
and printing separate:
#define PRINT(x) do { printf("%d\n", x); } while(0)
case 1: PRINT(1); ...
That being said, the following is possible, but not generally recommended:
#define CASE_PRINT(x) case (x): printf(#x "\n")
...
switch (a) {
CASE_PRINT(1); ...; break;
Note that in this version of the macro definition, the string for printf
is generated at compile-time which is more efficient. Whether or not that is a good idea compared to printf("%d\n", x)
depends on the situation and preferences. Consider for example this:
#define MOUSE_CLICK 1
...
switch (a) {
CASE_PRINT(MOUSE_CLICK); ...
With printf(#x, "\n")
this would print "MOUSE_CLICK", with printf("%d\n", x)
it would print "1".
If you must use a macro, then you'd write:
#define PRINT(x) x: printf(”%d\n”, x)
You'd have to use a semicolon after the macro invocation, not a colon.
However, this is not a good idea: fo the macro.