gpt4 book ai didi

c - _Generic() 宏不扩展

转载 作者:太空宇宙 更新时间:2023-11-04 00:29:11 25 4
gpt4 key购买 nike

所以我正在尝试实现“通用打印宏”:

#include <stdio.h>
#include <float.h>

#define CHECK(x) printf(#x " =" \
_Generic((x), float: double: "%f",\
int: "%d",\
default: "Cannot print this with CHECK(x)")\
, x)

int main(void){
CHECK(FLT_RADIX);
return 0;
}

这给我错误:

main.c:11:2: error: expected ')'
CHECK(FLT_RADIX);
^
main.c:5:3: note: expanded from macro 'CHECK'
_Generic((x), float: double: "%f",\
^
main.c:11:2: note: to match this '('
main.c:4:24: note: expanded from macro 'CHECK'
#define CHECK(x) printf(#x " =" \
^
1 error generated.

运行clang main.c -E后,输出为:

int main(void){
printf("FLT_RADIX" " =" _Generic((2), float: double: "%f", int: "%d", default: "Cannot print this with CHECK(x)") , 2);
return 0;
}

那么如何让_Generic()在翻译过程中展开呢?

顺便说一句:我不匹配哪个 )

最佳答案

_Generic 不是宏,而是 primary expression (另见 6.5.1.1)。因此,在字符串连接(阶段 6)之后的翻译阶段(7)对其进行评估。参见标准,5.1.1.2 .简而言之:当编译器连接字符串时,_Generic 尚未计算。

您必须将转换后的值作为字符串参数传递给 printf 或使用格式字符串调用单独的 printf 作为值。保持宏较小的一种方法是使用辅助函数,您传递类型代码加上 union 中的实际值。然后该函数将使用 switch 进行转换和打印。或者您对每种类型使用不同的函数。当然还有多种选择。

好的,这是一个(不一定是最好的)方法:

#define CHECK(x) _Generic((x), double: print_as_double(#x, x), \
float: print_as_double(#x, x),
int: print_as_int(#x, x), \
default: printf("Cannot print this with CHECK(x)") )

void print_as_float(const char *name, double value)
{
printf("%s = %lf", value);
}

...

请注意,您不能在通用关联 中组合不同的类型名称,这就是为什么我必须拆分floatdouble 条目的原因。

旁注:名称 CHECK 具有误导性,因为这些函数在运行时并不真正检查某些内容。更好的名字是例如“PRINT_VALUE”。

关于c - _Generic() 宏不扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36050446/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com