首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将复合文字传递给_Generic不起作用

将复合文字传递给_Generic不起作用
EN

Stack Overflow用户
提问于 2021-03-02 10:58:32
回答 3查看 81关注 0票数 3

在以下代码中:

代码语言:javascript
复制
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")

以下是工作原理:

代码语言:javascript
复制
struct Book ulysses = {"ulysses", "james"};
printf("%s\n", MYTYPE(ulysses));
struct Person jim;
jim = (struct Person) {"Tom", 20};
printf("%s\n", MYTYPE(jim));

但是,如果我尝试传递一个复合文字,它将失败:

代码语言:javascript
复制
printf("%s\n", MYTYPE((struct Person){"Tom", 10}));

gen.c:25:53:错误:宏"MYTYPE“传递了2个参数,但只接受1个参数

printf("%s\n",MYTYPE((struct Person){"Tom",10}));

....^

在过去的几年里,这似乎是一个什么问题?

宏?

更新:似乎用括号对表达式进行双包装可以解决这个问题,但我不确定为什么需要这样做:

代码语言:javascript
复制
printf("%s\n", MYTYPE(((struct Person){"Tom", 10})));
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-03-02 11:37:32

您已调用

有两个参数:

..。与圆括号不同,大括号在预处理器级别没有语法意义,并且不会抑制逗号作为宏参数分隔符的作用。您需要将复合文字括起来以避免这种情况。或者,在某些情况下(包括您的情况),您可以使用

来制作一个避免这个问题的变量宏。另请参阅我的问题:

复合文字和类似函数的宏: gcc或C标准中的错误?

票数 3
EN

Stack Overflow用户

发布于 2021-03-02 11:28:25

您遇到的问题是由于预处理器语法造成的。

使用两个参数调用MACRONAME的方法

,不管是否组合了

、逗号和

碰巧形成了一些语义上有效的表达式。(在预处理阶段,我们还没有将标记安排到表达式中)。

例外情况与字符串文字和匹配的括号对有关:

字符串文字中的逗号不是参数分隔符

匹配的括号对中的逗号不是分隔符。(这是指参数列表中的括号,而不是宏替换语法中的括号)。

这就是为什么双括号起作用的原因:

调用方法

只有一个参数

..。

票数 1
EN

Stack Overflow用户

发布于 2021-03-02 11:19:00

代码语言:javascript
复制
typedef struct Person {
    char* name;
    int age;
}      t_Person; // (sorry I took this habit)

请注意,如果您声明了它,则不再需要对其进行双包装:

代码语言:javascript
复制
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等。因此,编译器认为括号之间的结构实际上是强制转换而不是声明,添加另一个圆括号可以解决冲突。

我可以用以下几点来证明这一点:

代码语言:javascript
复制
#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限定符和原子性,并将数组到指针/函数到指针的转换应用于控制表达式的类型,而不会产生任何副作用或计算任何值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66432670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档