gpt4 book ai didi

C11 _Generic 用法

转载 作者:太空狗 更新时间:2023-10-29 17:19:01 29 4
gpt4 key购买 nike

我试图学习如何使用“新的”C11 泛型表达式,但我遇到了困难。

考虑以下代码:

#include <stdlib.h>
#include <stdio.h>

#define test(X, Y, c) \
_Generic((X), \
double: _Generic((Y), \
double * : test_double, \
default: test_double \
), \
int: _Generic((Y), \
int * : test_int, \
default: test_int \
) \
) (X, Y, c)


int test_double(double a, double *b, int c);
int test_int(int a, int *b, int c);

int test_double(double a, double *b, int c) { return 1; }
int test_int(int a, int *b, int c) { return 2; }

int main()
{
double *t = malloc(sizeof(double));
int *s = malloc(sizeof(int));
int a1 = test(3.4, t, 1);
int i = 3;
int a2 = test(i, s, 1);
printf("%d\t", a1);
printf("%d\n", a2);
return 0;
}

一切正常,但我仍然不明白为什么“_Generic((Y), ...”中的那些默认情况是必要的,而我可以在“_Generic((X),”的末尾省略它。 ..”没有后果。

事实上,如果我删除这两个默认值,我会得到一个错误(gcc 5.4.0)说“类型为‘double *’的选择器与任何关联都不兼容”,而宏扩展“int a1 = test(3.4, t, 1);"和“int *”一样,同时宏扩展 test(i, s, 1)

“默认”真的是必要的还是我遗漏了什么?在第一种情况下,到底为什么会这样?如果我只有 test_double 和 test_int 可以调用,为什么我应该为一些永远不应该编译的东西设置默认情况?

最佳答案

不幸的是,

_Generic 在标准中未指定。通常的解释似乎是未选择案例中的表达式不得包含任何约束违规。

一个更简单的例子:

int main(void)
{
int x;

_Generic(0, int: x = 5, float: x = (void)0);
}

此代码在 gcc 中给出了约束违规,因为它对所有关联的表达式(不仅仅是选定的表达式)执行约束检查,并且 x = (void)0 包含约束违规。


将此原则应用于没有默认大小写的代码,我们看到的问题是,当使用 Y 将宏实例化为声明为 int *s 的变量时,那么关联表达式之一是 _Generic(s, double * : test_double),这是一个约束违规,因为没有匹配的大小写。

关于C11 _Generic 用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40096584/

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