在以下代码中:
struct Person {
char* name;
int age;
};
struct Book {
char* title;
char* author;
};
#define MYTYPE(X) _Generic((X), int: "int", float: "float", double: "double", struct Book: "book", struct Person: "person", default: "other")以下是工作原理:
struct Book ulysses = {"ulysses", "james"};
printf("%s\n", MYTYPE(ulysses));
struct Person jim;
jim = (struct Person) {"Tom", 20};
printf("%s\n", MYTYPE(jim));但是,如果我尝试传递一个复合文字,它将失败:
printf("%s\n", MYTYPE((struct Person){"Tom", 10}));gen.c:25:53:错误:宏"MYTYPE“传递了2个参数,但只接受1个参数
printf("%s\n",MYTYPE((struct Person){"Tom",10}));
....^
在过去的几年里,这似乎是一个什么问题?
到
宏?
更新:似乎用括号对表达式进行双包装可以解决这个问题,但我不确定为什么需要这样做:
printf("%s\n", MYTYPE(((struct Person){"Tom", 10})));发布于 2021-03-02 11:37:32
您已调用
有两个参数:
和
..。与圆括号不同,大括号在预处理器级别没有语法意义,并且不会抑制逗号作为宏参数分隔符的作用。您需要将复合文字括起来以避免这种情况。或者,在某些情况下(包括您的情况),您可以使用
和
来制作一个避免这个问题的变量宏。另请参阅我的问题:
复合文字和类似函数的宏: gcc或C标准中的错误?
发布于 2021-03-02 11:28:25
您遇到的问题是由于预处理器语法造成的。
使用两个参数调用MACRONAME的方法
和
,不管是否组合了
、逗号和
碰巧形成了一些语义上有效的表达式。(在预处理阶段,我们还没有将标记安排到表达式中)。
例外情况与字符串文字和匹配的括号对有关:
字符串文字中的逗号不是参数分隔符
匹配的括号对中的逗号不是分隔符。(这是指参数列表中的括号,而不是宏替换语法中的括号)。
这就是为什么双括号起作用的原因:
调用方法
只有一个参数
..。
发布于 2021-03-02 11:19:00
typedef struct Person {
char* name;
int age;
} t_Person; // (sorry I took this habit)请注意,如果您声明了它,则不再需要对其进行双包装:
t_Person a = {"Tom", 10};
printf("%s\n", MYTYPE((((t_Person){"Tom", 10})))); -> works
printf("%s\n", MYTYPE(a)); -> works, saves 4 parenthesis.我的猜测是MYTYPE不知道它内部是什么,因为
_
泛型,它可以是int,float等。因此,编译器认为括号之间的结构实际上是强制转换而不是声明,添加另一个圆括号可以解决冲突。
我可以用以下几点来证明这一点:
#define MYTYPE(X) _Generic((X), char: "char", int: "int", float: "float", double: "double", struct Book: "book", struct Person: "person", default: "other")
printf("%s\n", MYTYPE((int){'a'})); // -> output int
printf("%s\n", MYTYPE((char){'a'})); // -> output char首先,控制表达式的类型进行左值转换
..。转换仅在类型域中执行:它丢弃顶级cvr限定符和原子性,并将数组到指针/函数到指针的转换应用于控制表达式的类型,而不会产生任何副作用或计算任何值。
https://stackoverflow.com/questions/66432670
复制相似问题