- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我试图学习如何使用“新的”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/
给定以下源代码: #include #include #include static inline void closedirp(DIR **p) { if (*p) c
在 C11 中,我可以创建一个原型(prototype)如下所示的函数: void myVaFunc(const char* const conv, ...); 我可以这样运行它: myVaFunc(
我正在阅读这个 C11 的 _Generic维基百科上的例子: #define cbrt(X) _Generic((X), long double: cbrtl, \
我需要在 C 中使用 _Generic,以便能够根据变量类型返回专门的值。 const char *encode_char_ptr(char *x) { return (x ? x : "NU
所以我正在尝试实现“通用打印宏”: #include #include #define CHECK(x) printf(#x " =" \ _Generic((x), float:
我试图学习如何使用“新的”C11 泛型表达式,但我遇到了困难。 考虑以下代码: #include #include #define test(X, Y, c) \ _Generic((X)
如何向 c11 _Generic Functions 添加额外类型? 您是否必须#undef/re-#define 它?(如果是这样,下面的工作是否可行)还是有更好的方法? #define to_st
我对 C11 的 _Generic 机制感到高兴 - 类型切换是我在 C++ 中怀念的东西。然而,事实证明它很难编写。 例如,给定函数: bool write_int(int); bool write
有没有办法在同一表达式中多次使用 _Generic 关键字来创建单个字符串文字? 我正在寻找的是一种生成单一格式字符串以传递给 printf 的方法,所有转换说明符都适合适当的类型。 写this时答案
我有一个这样的模板: template.h ---------- // Declare a function "func_type()" void JOIN(func_, T)(T t) { retu
我正在使用 C 的在线编译器和调试器。此网页使用 GCC 5.4.1 C99。当我测试这段代码时, https://www.onlinegdb.com/online_c_compiler #inclu
在下面的代码中: struct Person { char* name; int age; }; struct Book { char* title; char* au
我正在设置一些大宽度整数类型,因此我大量使用宏来使这些类型尽可能像基本整数类型一样可用。我一直遇到的一个问题是,如果我在宏扩展中大量使用 _Generic 表达式,而不是最小化 _Generic 使用
我想在C中组合两种类型来调用函数(例如具有不同列和行的乘法 vector 和矩阵): #define CC_FIRST(a) _Generic((a), int: int8d) #def
我有兴趣编写一个类型验证宏,它只在类型不是 int/short/long 或指针时发出警告。 我遇到的问题是指针可以是任何类型的指针。 #define INT_OR_POINTER_AS_UINTPT
我似乎无法将参数传递给需要不同参数的函数(或传递给实现第一个类型的子集的其他 _Generic 宏)。 #define DEBUG_PRINT(x,...) _Generic((x),
可能我在这里做错了一些非常基本的事情,但我无法弄清楚那可能是什么。我可以解释我的代码片段,但我认为我在这里尝试做的事情非常明显:为我的 DynamicArray 的 dynarr_printf 创建一
我正在尝试在 C11 中使用 _Generic 宏生成重载函数,并且我已经停止了对零参数函数的支持,例如: #define msg(_1) _Generic((_1), char*: msg_stri
使用 gcc.exe(Rev3,由 MSYS2 项目构建)8.2.0。 我试图构建一个宏来自动在两种类型之间进行类型转换,其中两个参数永远不应该是同一类型。我的问题是如果我不包含相同类型的情况,编译器
我想使用 C11 _Generic 关键字根据静态类型填充 union ,如: typedef union { double d; long l; const char*s;
我是一名优秀的程序员,十分优秀!