在C中使用_Generic类型在嵌套结构中进行函数重载

时间:2018-12-03 09:09:17

标签: c compiler-errors generic-programming c11

我正在尝试实现具有相似功能(不同参数)和两个或多个子结构作为成员的父结构。座右铭是实现这样的情况:我可以调用具有相同名称的函数,并根据其参数(结构类型)调用相关的成员函数。

当我尝试如下实现时,gcc编译器给出错误,指出_Generic中指定的标识符不正确。那么,要使用的正确标识符是什么?如何解决此错误!

P.S .:该程序实际上是我正在实施的一个较大程序的原型。因此,它仅用于澄清我的实际问题。

谢谢。

C代码:

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

typedef struct myint{
         int mem;
}INT;

typedef struct mydouble{
      double mem;
}DOUBLE;

typedef struct head{
    INT *integer;
    DOUBLE *d_precision;
    int (*x)(INT *p);
    double (*xf)(DOUBLE *u);
}H;

int x(INT *p){
    p->mem= 2;
    return p->mem*p->mem;
}

double xf(DOUBLE *u){
    u->mem= 2.2;
    return u->mem*u->mem;
}

#define x(a) _Generic(a, struct myint*: x, DOUBLE*: xf)(a)

int main(void){
    H *ptr = (H *)malloc(sizeof(H));

    INT *i = (INT *)malloc(sizeof(INT));
    ptr->integer = i; 
    DOUBLE *f = (DOUBLE *)malloc(sizeof(INT));
    ptr->d_precision = f;

    printf("%d", (*ptr).x(ptr->d_precision));
    printf("%f", (*ptr).x(ptr->integer));

    return 0;
}

================================================ ========================= 编译器输出:

root@kali:~# gcc -std=c11 -o generic3 generic3.c
generic3.c: In function ‘main’:
generic3.c:30:14: error: expected identifier before ‘_Generic’
 #define x(a) _Generic(a, struct myint*: x, DOUBLE *: xf)(a)
              ^~~~~~~~
generic3.c:40:22: note: in expansion of macro ‘x’
  printf("%d", (*ptr).x(ptr->d_precision));
                      ^
generic3.c:30:14: error: expected identifier before ‘_Generic’
 #define x(a) _Generic(a, struct myint*: x, DOUBLE *: xf)(a)
              ^~~~~~~~
generic3.c:41:22: note: in expansion of macro ‘x’
  printf("%f", (*ptr).x(ptr->integer));

2 个答案:

答案 0 :(得分:0)

读取the reference for _Generic时,似乎第二个参数是表达式的列表,而不是任意标记序列。
对于您来说,_Generic是在编译器级别处理的,前提是预处理的源代码必须已经在语法上有效,而实际上不是:

printf("%d", (*ptr)._Generic(ptr->d_precision, struct myint*: x, double: xf)(ptr->d_precision));
//                 ^^^^^^^^^ ???

答案 1 :(得分:0)

删除def __len__(self): return self.spec.shape[0] # as said of course you can also choose other dimensions 前缀。这是C而不是C ++。