如果嵌套,C11 _Generic() 表达式会失败

标签 c c11

我试图找出为什么嵌套 _Generic() 表达式对我来说失败。如果我不嵌套它们,它们就可以正常工作。

当然,这在一个较长的程序中发生在我身上,但我将其总结为一个最小的工作示例,它触发了与较大程序中完全相同的错误。

我尝试一遍又一遍地检查代码,但没有找到确凿的证据...问题的原因是什么?

#include <stdio.h>

typedef struct sta
    {
    char a;
    }ta;

typedef struct stb
    {
    short b;
    }tb;

typedef struct stc
    {
    int c;
    }tc;

#define MAGICNUMBER(X) _Generic((X), \
ta: 1, \
tb: 2, \
tc: 3 \
)

#define NESTEDMAGICNUMBER3(X) _Generic((X), \
ta: 1 \
)

#define NESTEDMAGICNUMBER2(X) _Generic((X), \
tb: 2, \
default: NESTEDMAGICNUMBER3(X) \
)

#define NESTEDMAGICNUMBER(X) _Generic((X), \
tc: 3, \
default: NESTEDMAGICNUMBER2(X) \
)

int     main(int argc, char *argv[])
    {
    ta a;
    tb b;
    tc c;
    
    printf("direct macro: ta has # %d\n",MAGICNUMBER(a));
    printf("direct macro: tb has # %d\n",MAGICNUMBER(b));
    printf("direct macro: tc has # %d\n",MAGICNUMBER(c));
    printf("nested macro: ta has # %d\n",NESTEDMAGICNUMBER(a)); /* Compile-time error why? */
    printf("nested macro: tb has # %d\n",NESTEDMAGICNUMBER(b)); /* Compile-time error why? */
    printf("nested macro: tc has # %d\n",NESTEDMAGICNUMBER(c)); /* Compile-time error why? */
    
    return 0;
    }

编译时,我得到这个:

cc -o testgeneric testgeneric.c
testgeneric.c:49:39: error: controlling expression type 'tb' (aka 'struct stb') not compatible with any generic association type
        printf("nested macro: tb has # %d\n",NESTEDMAGICNUMBER(b)); /* Compile-time error why? */
                                             ^~~~~~~~~~~~~~~~~~~~
testgeneric.c:36:10: note: expanded from macro 'NESTEDMAGICNUMBER'
default: NESTEDMAGICNUMBER2(X) \
         ^~~~~~~~~~~~~~~~~~~~~
testgeneric.c:31:10: note: expanded from macro 'NESTEDMAGICNUMBER2'
default: NESTEDMAGICNUMBER3(X) \
         ^~~~~~~~~~~~~~~~~~~~~
testgeneric.c:25:40: note: expanded from macro 'NESTEDMAGICNUMBER3'
#define NESTEDMAGICNUMBER3(X) _Generic((X), \
                                       ^~~
testgeneric.c:50:39: error: controlling expression type 'tc' (aka 'struct stc') not compatible with any generic association type
        printf("nested macro: tc has # %d\n",NESTEDMAGICNUMBER(c)); /* Compile-time error why? */
                                             ^~~~~~~~~~~~~~~~~~~~
testgeneric.c:36:10: note: expanded from macro 'NESTEDMAGICNUMBER'
default: NESTEDMAGICNUMBER2(X) \
         ^~~~~~~~~~~~~~~~~~~~~
testgeneric.c:31:10: note: expanded from macro 'NESTEDMAGICNUMBER2'
default: NESTEDMAGICNUMBER3(X) \
         ^~~~~~~~~~~~~~~~~~~~~
testgeneric.c:25:40: note: expanded from macro 'NESTEDMAGICNUMBER3'
#define NESTEDMAGICNUMBER3(X) _Generic((X), \
                                       ^~~
2 errors generated.

为什么嵌套版本会失败,而非嵌套版本却可以正常工作?

谢谢!

最佳答案

Why does the nested version fail, while the non-nested version works fine?

考虑NESTEDMAGICNUMBER(b))的扩展:

_Generic((b), tc: 3, default: _Generic((b), tb: 2, default: _Generic((b), ta: 1 ) ) )

编译器拒绝此表达式,因为子表达式 _Generic((b), ta: 1 ) 由于没有 b 类型的情况而无效(tb,又名struct stb)。事实上,这不是将要选择的通用替代方案的一部分,这一事实是无关紧要的——程序源代码中的每个表达式和子表达式都必须有效,无论它是否有任何效果。您可以通过添加 default 替代 NESTEDMAGICNUMBER3 来解决该问题:

#define NESTEDMAGICNUMBER3(X) _Generic((X), \
ta: 1, \
default: 0 \
)

关于如果嵌套,C11 _Generic() 表达式会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65654835/

相关文章:

c - 为什么结构体中的变量没有被分配任何值?

c - 并行化给出错误的输出

c - (void)strcpy(somevariable1, somevariable2) 正确吗?

c - 整数上的无分支条件——很快,但它们能变得更快吗?

c - 将两个无符号数的减法存储为有符号数的语义

c++ - 在堆栈上分配对齐的内存,如 _alloca

将 32 位网络命令转换为 C 中的主机

c - C 中的 Visual Studio 错误,0xfefefefe 处未处理的异常

c - 严格的别名规则背后的基本原理是什么?

c - 你如何将 MAC 地址(在数组中)转换为 C 中的字符串?