C11中_Generic的语法和示例用法

App*_*ker 66 c generics c11

我听说C11添加了泛型.我已经google了一下,看了一些文章,了解到有一个新的关键字(_Generic)和所有.但我似乎无法把握住这一切.

它是类似C#中的泛型还是C++中的模板?任何人都可以简单解释一下C11的泛型定义,它的语法和一个简单的示例用法示例吗?

Ale*_*ray 84

我见过的最好的例子激发了以下(可运行的)示例,它解开了各种怪异的可能性,用于破解内省...

#include <stdio.h>
#include <stddef.h>
#include <stdint.h>

#define typename(x) _Generic((x),        /* Get the name of a type */             \
                                                                                  \
        _Bool: "_Bool",                  unsigned char: "unsigned char",          \
         char: "char",                     signed char: "signed char",            \
    short int: "short int",         unsigned short int: "unsigned short int",     \
          int: "int",                     unsigned int: "unsigned int",           \
     long int: "long int",           unsigned long int: "unsigned long int",      \
long long int: "long long int", unsigned long long int: "unsigned long long int", \
        float: "float",                         double: "double",                 \
  long double: "long double",                   char *: "pointer to char",        \
       void *: "pointer to void",                int *: "pointer to int",         \
      default: "other")

#define fmt "%20s is '%s'\n"
int main() {

  size_t s; ptrdiff_t p; intmax_t i; int ai[3] = {0}; return printf( fmt fmt fmt fmt fmt fmt fmt fmt,

     "size_t", typename(s),               "ptrdiff_t", typename(p),     
   "intmax_t", typename(i),      "character constant", typename('0'),
 "0x7FFFFFFF", typename(0x7FFFFFFF),     "0xFFFFFFFF", typename(0xFFFFFFFF),
"0x7FFFFFFFU", typename(0x7FFFFFFFU),  "array of int", typename(ai));
}
Run Code Online (Sandbox Code Playgroud)
                 ????????????????? 
?????????????????? Amazeballs... ??????????????????????????????????????
                 ????????????????? 
            size_t is 'unsigned long int'
         ptrdiff_t is 'long int'
          intmax_t is 'long int'
character constant is 'int'
        0x7FFFFFFF is 'int'
        0xFFFFFFFF is 'unsigned int'
       0x7FFFFFFFU is 'unsigned int'
      array of int is 'other'
Run Code Online (Sandbox Code Playgroud)

  • 这很整洁,但你永远不能用这种方式覆盖所有类型...无论如何,+1为"Amazeballs"...... (9认同)
  • 实际上,@einpoklum,您可以通过这种方式涵盖所有非复合类型...有 5 种整数类型及其无符号对应类型,以及 3 种浮点类型及其复杂对应类型,总共 16 种基本类型。当您包含存储类(普通、“const”、“易失性”和“易失性常量”)时,会提供 64 种不同的变体。虽然麻烦,但并非不可能。指向每种类型的指针都会使该数字加倍,而指针到指针则进一步增加该数字...但这总共提供了 192 种变体...呃!但仍然不是不可能。 (3认同)

unw*_*ind 49

是一个非常好的介绍.这是概述:

通用选择使用新关键字实现:_Generic.语法类似于类型的简单switch语句:_Generic( 'a', char: 1, int: 2, long: 3, default: 0) 计算结果为2(字符常量是C中的整数).

基本上它就像一种类型switch,其中标签是类型名称,它们根据第一个表达式('a'上面)的类型进行测试.结果成为评估结果_Generic().


izh*_*nte 5

我使用的是clion 1.2.4,而clion现在不支持c11,因此我在c99中使用以下代码而不是_Generic

#include <stdio.h>

int main(int argc, char **argv) {
    char *s;
    if (__builtin_types_compatible_p(__typeof__(s), long)) {
        puts("long");
    } else if (__builtin_types_compatible_p(__typeof__(s), char*)) {
        puts("str");
    }
    return (0);
};
Run Code Online (Sandbox Code Playgroud)

  • “这是我使用的而不是 _Generic 的东西”如何在一个问题上获得 8 个赞成票,该问题要求举例说明如何使用 _Generic (13认同)
  • 这是 GNU C,不是 C99 (3认同)
  • @MichaelMrozek-此答案提供了一种替代方法,如果没有其他要求,则可以说明被询问的概念_。_anything_的替代方法的一个特征是,它将始终对被询问的事物提供新的独特观点。老师一直在使用这种技术。如果您站在一个地方凝视着某个东西却又不了解它,那么请走过去,从另一个角度看待它。这总是提供新的信息。那,无论是否有意,都是这个答案提供的一件事。(为此+1) (2认同)