我试图找出为什么嵌套 _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/