Return C 中表达式的种类,即它是右值还是左值

Return the kind of an expression in C, i.e., whether it's an rvalue or lvalue

我可以打印表达式的计算方式吗?

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

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

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

supports_lvalue(*(int *)4)

不过,这只是假设,可能会被留给只是玩弄基本的例子。

原因只是为了实验,但如果可能的话,它可能对调试有用。

左值指向一个可以赋新值的存储位置。包括 const 变量在内的所有变量都是左值。左值持续存在于使用它的表达式之外。另一方面,右值是一个临时值,不会在使用它的表达式之外持续存在。 左值可能出现在赋值运算符的左侧或右侧。但是右值永远不能出现在赋值运算符的左侧。

简而言之:左值是存储区,右值是值。

示例:

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;
}

当您错误地使用左值或右值时会出现编译错误。

根据C Standard, section 6.3.2.1

An lvalue is an expression (with an object type other than void) that potentially designates an object.

虽然这很含糊,但它继续

The name ‘‘lvalue’’ comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue.

还有更多

What is sometimes called ‘‘rvalue’’ is in this International Standard described as the ‘‘value of an expression’’.

这对我来说意味着什么

An lvalue is a value that supports assignment and is on the left side of the assignment operator.

An rvalue is any value not on the left hand side of the assignment operator.

例如

#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;
}

如上评论并完整回答问题

You'd have to use a compiler that lets you access the AST of a given compilation unit.