C 获取使用三元运算符选择的变量的地址时发生编译错误
下面我通过获取一个变量的地址进行编译,该变量是使用三元运算符选择的。我正在犯错误 错误:一元'&'操作数需要左值C 获取使用三元运算符选择的变量的地址时发生编译错误,c,gcc,C,Gcc,下面我通过获取一个变量的地址进行编译,该变量是使用三元运算符选择的。我正在犯错误 错误:一元'&'操作数需要左值 我的代码中有很多这样的实例,所以我希望有一个解决方案,它可能只需要单独更改宏,而不是像#define GETINT()((a==1)?&b:&c),因为我在代码中的其他几个地方使用它来选择b和c之间的整数。万一没有解决办法,谁能解释它出了什么问题。顺便说一句,这段代码是用Green Hills C编译器编译的,但是如果您扩展得到的 &((a==1) ? b : c) 这是无
我的代码中有很多这样的实例,所以我希望有一个解决方案,它可能只需要单独更改宏,而不是像
#define GETINT()((a==1)?&b:&c)
,因为我在代码中的其他几个地方使用它来选择b和c之间的整数。万一没有解决办法,谁能解释它出了什么问题。顺便说一句,这段代码是用Green Hills C编译器编译的,但是如果您扩展得到的
&((a==1) ? b : c)
这是无效的C
你需要这个:
#define GETINT() ((a==1) ? &b : &c)
....
int *ptr = GETINT();
如果展开
&GETINT()
,您将得到
&((a==1) ? b : c)
这是无效的C
你需要这个:
#define GETINT() ((a==1) ? &b : &c)
....
int *ptr = GETINT();
问题正是编译器所说的,
&
的参数必须是左值,而您可以使用?:
传递表达式
出于同样的原因,您也不能这样做:
((a == 1) ? b : c) = 4711; /* BAD CODE */
您确实应该在宏中包含&
,并且在需要实际值时只需取消引用即可:
#define GETINTPTR(a) ((a == 1) ? &b : &c)
#define GETINT(a) *GETINTPTR(a)
当然,
GETINT()
宏有点傻,您可以直接在代码中使用*GETINTPTR()
。问题正是编译器所说的,&
的参数必须是左值,而您可以使用?:
传递表达式
出于同样的原因,您也不能这样做:
((a == 1) ? b : c) = 4711; /* BAD CODE */
您确实应该在宏中包含&
,并且在需要实际值时只需取消引用即可:
#define GETINTPTR(a) ((a == 1) ? &b : &c)
#define GETINT(a) *GETINTPTR(a)
当然,
GETINT()
宏有点傻,您可以直接在代码中使用*GETINTPTR()
。根据C11
标准,第6.5.15章,条件表达式
[…]结果是第二个或第三个操作数的值
(以计算值为准),转换为下述类型。(110)
不动产,脚注(110)
条件表达式不会产生左值
OTOH,根据第6.5.3.2章(重点矿山)
一元&
运算符的操作数应为函数指示符,[]或一元*运算符的结果,或指定非位字段且未使用寄存器存储类指示符声明的对象的左值
因此,您的代码无效
解决方案:像这样编写宏
#define GETINT(a,b,c) ((a==1) ? &b : &c)
像这样使用它
int *ptr = GETINT(a,b,c);
根据
C11
标准,第6.5.15章,条件表达式
[…]结果是第二个或第三个操作数的值
(以计算值为准),转换为下述类型。(110)
不动产,脚注(110)
条件表达式不会产生左值
OTOH,根据第6.5.3.2章(重点矿山)
一元&
运算符的操作数应为函数指示符,[]或一元*运算符的结果,或指定非位字段且未使用寄存器存储类指示符声明的对象的左值
因此,您的代码无效
解决方案:像这样编写宏
#define GETINT(a,b,c) ((a==1) ? &b : &c)
像这样使用它
int *ptr = GETINT(a,b,c);
最后,我解决了这个问题,只需更改宏即可实现这两个目的。 #定义GETINT()(*((a==1)?&b:&c)) 下面是代码
#define GETINT() (*((a==1) ? &b : &c))
void main()
{
int a = 1, b = 2, c = 3;
int *ptr = &GETINT();
int d = GETINT();
printf("%d %d\n", *ptr, d);
}
最后,我解决了这个问题,只需更改宏即可实现这两个目的。 #定义GETINT()(*((a==1)?&b:&c)) 下面是代码
#define GETINT() (*((a==1) ? &b : &c))
void main()
{
int a = 1, b = 2, c = 3;
int *ptr = &GETINT();
int d = GETINT();
printf("%d %d\n", *ptr, d);
}
这不是为什么无效的问题吗?这不是为什么无效的问题吗?尽管注释不是规范性的。规范性文本说明您想要的结果是第二个或第三个操作数的值。强调值。@ShafikYaghmour先生,我刚才引用了相关脚注。然而,根据你的建议,更新了我的asnwer。希望现在好一点。虽然,注释不规范。规范性文本说明您想要的结果是第二个或第三个操作数的值。强调值。@ShafikYaghmour先生,我刚才引用了相关脚注。然而,根据你的建议,更新了我的asnwer。希望现在更好。对现有答案进行一点扩展-有条件的
?:代码>表达式在运行时计算。它返回一个不需要特定地址的值(通常在CPU寄存器中)。因此,一般来说,和
不能保证为结果提供合理的地址-这大概就是为什么结果被定义为“右值”而不是“左值”的原因。在现有答案的基础上稍微扩展一下-有条件的?:代码>表达式在运行时计算。它返回一个不需要特定地址的值(通常在CPU寄存器中)。所以一般来说,&
不能保证为结果提供一个合理的地址,这大概就是为什么结果被定义为“右值”而不是“左值”;这让我明白了这个问题。谢谢你放松,((a==1)?b:c)=4711;这让我明白了问题所在。