返回C中表达式的类型,即它是否是左值或左值

时间:2016-06-11 07:52:25

标签: c expression lvalue rvalue

我可以打印如何评估表达式吗?

例如,如果我想知道某个值是否被评估为右值或左值,我会调用假设代码:

int main() {
    if(isrvalue(*(int *)4)) return 0;
    else return 1;
}

这会产生问题,因为我们会在下面发现'类型'表达式可以取决于它是在赋值运算符的右侧还是左侧。所以测试更适合

supports_lvalue(*(int *)4)

虽然这只是假设,可能只是在玩基本的例子。

原因仅在于实验,但如果有可能,它可能在调试中很有用。

2 个答案:

答案 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的编译器。