我可以打印如何评估表达式吗?
例如,如果我想知道某个值是否被评估为右值或左值,我会调用假设代码:
int main() {
if(isrvalue(*(int *)4)) return 0;
else return 1;
}
这会产生问题,因为我们会在下面发现'类型'表达式可以取决于它是在赋值运算符的右侧还是左侧。所以测试更适合
supports_lvalue(*(int *)4)
虽然这只是假设,可能只是在玩基本的例子。
原因仅在于实验,但如果有可能,它可能在调试中很有用。
答案 0 :(得分:2)
左值指向可以分配新值的存储位置。包括const
变量在内的所有变量都是左值。左值超出了使用它的表达式。另一方面,rvalue是一个临时值,不会超出使用它的表达式。
左值可能出现在赋值运算符的左侧或右侧。但是rvalues永远不会出现在赋值运算符的左侧。
简而言之:Lvalues是存储区域,rvalues是值。
示例:
int main(){
int i = 10;
int j = 20;
int* ip;
int* jp;
/* ip and jp are pointer variables, hence L-VALUES.
they can appear BOTH sides of = operator.
as shown below.
*/
ip = &i;
jp = &j;
jp = ip;
/* values such as 1, 25, etc are Values, hence R-VALUES
they can appear only RIGHT side of = operartor
as shown below, 1 on left causes error not ip
*/
ip + 1 = &i; // invalid
ip = &i + 1; // valid, however printf("%d", *ip); might print a Garbage value
/* *ip and *jp are also L-VALUES, including *(ip + 1) or *(ip + 2)
they can appear both sides
*/
*ip = 1 + *jp;
return 0;
}
错误地使用左值或右值时会出现编译错误。
答案 1 :(得分:0)
根据C Standard, section 6.3.2.1:
左值是一个表达式(对象类型不是void),可能指定一个对象。
虽然这是相当模糊的,但仍在继续
名称''左值'最初来自赋值表达式 E1 = E2,其中左操作数 E1 需要是(可修改的)左值。
还有更多
有时被称为''rvalue'的东西在本国际标准中被描述为''表达的价值''。
这对我意味着什么
左值是一个支持赋值的值,位于赋值运算符的左侧。
rvalue 是任何不在赋值运算符左侧的值。
所以例如
#include <stdio.h>
int main() {
int array[1], *pointer, i = 42;
// ^ ^-rvalue
// lvalue
*array = i;
// ^ ^-rvalue
//lvalue
pointer = array;
// ^ ^-rvalue
//lvalue
printf("%p\t%d\n", pointer, *pointer);
// ^-rvalues-^
// causes segfault but compiles:
*(int *)4 = 2;
// ^ ^-rvalue
// lvalue
return 0;
}
如上所述在评论中并完全回答问题
您必须使用允许您访问给定编译单元的AST的编译器。