我知道如何简单地避免lvalue required as unary ‘&’
错误(如这里)
我想做的是避免在一行中出现这个错误。为什么?我定义了很多const,在我编写的一些糟糕的代码中,这些const被用于初始化。我不想每次使用时都定义一个中间变量…
在下面的例子中,我需要中间值't'int * p;
const int q = 88;
int t = (int)q; //works but I have to add for each time I used q, an intermediate variable.
p = &t;
printf("p: %un",*p);
在下面的例子中,我不需要中间值't'(但它不起作用)
int * p;
const int q = 88;
p = &((int)q); //what I would like to do but raises: error: lvalue required as unary ‘&’ operand
printf("p: %un",*p);
有单行道吗?使用#define可能是一个提示…
注意:我显然不希望在我的编译中出现任何警告,因为我正在纠正MISRA违规:Cast from 'const int *' removes 'const' qualifier (MISRAC2012-RULE_11_8.a)
注意:p没有声明为const int,因为p稍后会被修改。P使用I来初始化自己。
如果变量很简单,则'StoryTeller - Unslander Monica'给出的解决方案有效:p = &((int){i});
但是这不适用于结构体:
typedef struct
{
int i;
int j;
}struct_t;
const struct_t q = {.i=12,.j=88};
printf("q: %u - %un",q.i,q.j);
struct_t * p = &((struct_t){q});
printf("p: %u - %un",p->i,p->j);
其编译引发error: incompatible types when initializing type ‘int’ using type ‘struct_t {aka const struct }’
像(int)i
这样的强制转换表达式确实不是左值。然而,复合文字是和左值:
p = &(int){i};
它本质上产生一个具有自动存储持续时间的匿名整数,从i
初始化,并持续到封闭作用域结束。
所以你也得到了一个有效的指针
使用结构改变了游戏环境。因为初始化列表的语义在标量和聚合之间是不同的。但这并不意味着我们不能以统一的方式工作。只需创建一个数组(包含1个元素),因此我们总是初始化一个封闭的聚合。现在这两个代码片段都可以工作了
// p = (int[]){i};
struct_t *p = (struct_t[]){q};
虽然到指针的转换是隐式的(这可能会引发争论)。