C11 _Generic() - 如何抑制与选择器

时间:2017-10-06 06:52:40

标签: c gcc c11

P.S.-我为了简单起见使用了int和int *,它也可以是struct和struct *。

我正在尝试实现一个宏,将一个变量中存在的数据复制到另一个独立于变量数据类型的数据中。在下面的解决方案中,我使用的是'_Generic'编译器功能。 计划1:

#include<stdio.h>
#include <string.h>

#define copyVar(var,newVar) _Generic((var),int:({memcpy(newVar,(void *)&var,sizeof(int));}),\
        int *:({memcpy(newVar,(void *)var,sizeof(int));}),default:newVar=var)
int main() {
   int data = 2;
   int *copy;copy = (int *)malloc(sizeof(int));
   copyVar(data,copy);
   printf("copied Data=%i",*copy);
}

计划2:

  #include<stdio.h>
  #include <string.h>

    #define copyVar(var,newVar) _Generic((var),int:({memcpy(newVar,(void *)&var,sizeof(int));}),\
                int *:({memcpy(newVar,(void *)var,sizeof(int));}),default:newVar=var)
 int main() {
           int data = 2;
           int *copy;copy = (int *)malloc(sizeof(int));
           copyVar(&data,copy);
           printf("copied Data=%i",*copy);
}

现在的问题是,尽管有一些警告,'程序1'仍然可以成功编译。 但是在编译程序时2 gcc抛出错误:

  

错误:左撇子需要作为一元'&amp;'操作数#define   copyVar(var,newVar)_Generic((var),int:({memcpy(newVar,(void)   *)及变种,的sizeof(INT));}),

我认为这是因为_Generic int:选择得到一个额外的&符号预处理

  

(void *)&amp;&amp; var

为什么gcc会评估所有选择?

3 个答案:

答案 0 :(得分:4)

您的代码存在各种问题:您将数据复制到未初始化的指向,您有多余的void *强制转换,您将WebElement AgreeandContinue= driver.findElement(By.xpath("//input[@id='confirmButtonTop']")); 视为某种复合语句而不是表达式,依此类推。

但是要回答你的问题,你的代码不起作用,因为_Generic的结果不是左值。由于&something运算符需要左值,因此您无法执行&。 (并且你不能& &something,因为它被“最大规则”处理为&amp;&amp;运算符。)

因此,由于此代码不起作用,您的代码无法正常工作:

&&something

gcc告诉您int x; int**p = & &x; 不是左值:

  

左撇子需要作为一元'&amp;'操作数

编辑 - 澄清

与任何宏一样,此&x宏的工作方式类似于预处理器文本替换。所以当你在宏中有这个代码时:

_Generic

它被预处理为

_Generic((var), ...
int: ... (void *)&var
int*: ... (void)var

_Generic((&data), ... int: ... (void *)& &data int*: ... (void)&data 表达式的所有路径都经过预处理。 _Generic本身不是预处理器的一部分,但稍后会被评估,就像任何包含运算符的表达式一样。检查整个表达式的语法正确性,即使只评估和执行表达式的一部分。

答案 1 :(得分:1)

_Generic的缩进原始用法与函数指针一样

#define copyVar(var,newVar) \
     _Generic((var),        \
        int:    function1,  \
        int*:   function2,  \
        default:function3)(&(var), &(newVar))

这里通用表达式选择函数,然后将此函数应用于任何参数。

您必须编写与三种不同情况相对应的三个存根函数。

如果你的头文件中有小而好的inline,那么优化器通常会确保这个机制没有运行时开销。

答案 2 :(得分:0)

可以通过两个级别的_Generic来解决

decimal