C++中的投射和指针投射

Casting and pointer casting in C++

本文关键字:指针 C++      更新时间:2023-10-16

谁能解释我为什么这是真的:

char *p;
short  i;
long l;
(long *) p = &l ;       /* Legal cast   */
(long) i = l ;          /* Illegal cast */

我知道它与左值和右值有关,但(long *) p不应该是右值吗?

编辑:

抱歉,我

似乎让自己和其他人感到困惑,我在阅读"这个 MDSN"时问了这个问题,我很惊讶地看到这个语法,我看到它是一个特殊功能,只要它的大小相同,就可以将左值转换为左值。

这些表达式都不合法,它们都应该无法编译。

C++11, 5.17.1:

赋值运算符 (=) 和复合赋值运算符都从右到左分组。所有这些都需要一个可修改的左操作数作为它们的左操作数,并返回一个引用左操作数的左键值。

5.4:

显式类型转换(强制转换表示法) [expr.cast] 1 表达式 (T) 强制转换表达式的结果是 T 类型。如果 T 是左值引用类型或对函数类型的右值引用,则结果为 lvalue,如果 T 是对对象类型的 rvalue 引用,则结果为 xvalue;否则,结果为 PR值。

因此,这两个表达式都违反了这些约束。

(长*)p不应该是右值吗?

是的。

它们都是 prvalue,因此,这两个语句的格式都不正确:

[C++03: 5.4/1]: 表达式(T)强制转换表达式的结果T 类型。如果T是引用类型,则结果为左值,否则结果为右值

[C++11: 5.4/1]: 表达式(T)强制转换表达式的结果T 类型。如果T是左值引用类型或对函数类型的右值引用,则结果为左值,如果T是对对象类型的右值引用,则结果为 xvalue;否则,结果为 PR值[..]

GCC 4.8拒绝了你的"合法强制",但Visual Studio有一个扩展接受这一点(没有明显的原因)。

值转换的结果是右值。不能赋值基本类型。

换句话说,对于int a = 10;aint 类型的左值,但(long) along 类型的临时右值,你不能分配给临时右值。指针也是如此。

为什么你认为你的演员阵容是合法的?我在两个演员阵容上都得到了error C2106: '=' : left operand must be l-value

这不应该是合法的。如果你真的想这样做,你必须像这样投射它:

(long*&)p = &l; // equivalent to *(long**)&p = &l

但除非你知道自己在做什么,否则不要这样做。