gpt4 book ai didi

C11 _Generic() - 如何抑制与选择器不匹配的选择的 gcc 代码评估(错误检查)

转载 作者:太空狗 更新时间:2023-10-29 16:10:24 25 4
gpt4 key购买 nike

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 时抛出错误:

error: lvalue required as unary '&' operand #define copyVar(var,newVar) _Generic((var),int:({memcpy(newVar,(void *)&var,sizeof(int));}),

我认为这是因为 _Generic int: selection get preprocessed with another & 符号

(void *)&&var

为什么 gcc 评估所有选择?

最佳答案

您的代码存在各种问题:您将数据复制到一个未初始化的指针中,您有多余的 void* 强制转换,您将 _Generic 视为某种复合语句而不是表达式,等等。

但要回答您的问题,您的代码不起作用,因为 &something 的结果不是左值。由于 & 运算符需要一个左值,因此您不能执行 & &something。 (而且您也不能执行 &&something,因为它被“最大咀嚼规则”视为 && 运算符。)

因此您的代码无法正常工作的原因与此代码无法正常工作的原因相同:

int x;
int**p = & &x;

gcc 告诉你 &x 不是左值:

lvalue required as unary '&' operand


编辑 - 澄清

这个 _Generic 宏,像任何宏一样,像预处理器文本替换一样工作。所以当你在宏中有这段代码时:

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

它被预处理为

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

_Generic 表达式的所有路径都经过预处理。 _Generic 本身不是预处理器的一部分,但会在稍后计算,就像任何包含运算符的表达式一样。检查整个表达式的句法正确性,即使只评估和执行表达式的一部分。

关于C11 _Generic() - 如何抑制与选择器不匹配的选择的 gcc 代码评估(错误检查),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46599901/

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