简体   繁体   中英

Difference between cast used in Compound literals and that done on a pointer variable?

Consider the following code:

int main()
{ 
    int *p;

    ++((int){5});    //compile without err/warning
    &((int){5});     //compile without err/warning

    ++((char *)p);   //Compile-time err: invalid lvalue in increment
    &((char *)p);    //Compile-time err: invalid lvalue in unary '&'

}

Why do the Compound Literals do not generate errors here?

It is because the "cast" in a compound literal is not a cast at all - it just looks like one.

A compound literal (which is the complete construction (int){5} ) creates an lvalue. However a cast operator creates only an rvalue, just like most other operators.

This example would be allowed (but useless, just like your int examples):

++((char *){(char *)p});
&((char *){(char *)p});

Compound literal doesn't have a cast in it. The (int) part of your compound literals is not a cast. It is just a type part of compound literal syntax. So, the question in this case is whether a compound literal is an object, an lvalue. The answer is yes, a compound literal is an lvalue. For this reason you can apply any operators to it that require an lvalue (like ++ or & ).

The second part of your example contains casts. The result of a cast is always an rvalue. You can't use ++ and & with rvalues.

The "cast" in a compound literal is actually not a cast , rather it is the type of the compound literal.
So, (int){5} is indeed more like an anonymous int , hence a valid lvalue which can be used anywhere an object of the same type ( int in this case) could be used.

Whereas, (char *)p is actually a cast ( rvalue ), so it cannot be incremented ++ or referenced & .

Read Dr.Doobs's in-depth article about compound literals.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM