最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - Why does this macro with a comma operator fail to compile in a switch statement? - Stack Overflow

programmeradmin5浏览0评论
#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?

Share Improve this question edited Mar 17 at 8:08 Alphin Thomas asked Mar 17 at 7:17 Alphin ThomasAlphin Thomas 1 2
  • 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
Add a comment  | 

3 Answers 3

Reset to default 6

case 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.

发布评论

评论列表(0)

  1. 暂无评论