C++ 中的类型转换和指针类型转换
Posted
技术标签:
【中文标题】C++ 中的类型转换和指针类型转换【英文标题】:Casting and pointer casting in C++ 【发布时间】:2014-01-01 17:19:09 【问题描述】:谁能解释一下为什么会这样:
char *p;
short i;
long l;
(long *) p = &l ; /* Legal cast */
(long) i = l ; /* Illegal cast */
我知道它与左值和右值有关,但 (long *) p
不应该是右值吗?
编辑:
对不起,我似乎把自己和其他人弄糊涂了,我在阅读"this MDSN" 时问了这个问题,我很惊讶地看到这个语法,我看到它是一个特殊功能,只要它的大小相同,就可以将左值转换为左值。
【问题讨论】:
两者都不是有效的 C++,这不应该编译。任何一种转换的结果都是您无法分配的右值。 这些都不适合我。 好吧,我不明白 (1) 是如何合法的。根据我的clang++
,它不是。他们都是错误的。
关于编辑:这很奇怪。如果这两种类型的大小相同,那为什么不直接说p = (char *) &l
?
【参考方案1】:
这些表达式都不合法,它们都应该编译失败。
C++11、5.17.1:
赋值运算符 (=) 和复合赋值运算符都从右到左分组。都需要一个可修改的左值作为左操作数,并返回一个指向左操作数的左值。
5.4:
显式类型转换(强制转换表示法)[expr.cast] 1 表达式 (T) cast-expression 的结果是 T 类型。如果 T 是左值引用类型或对函数类型的右值引用,则结果是左值;如果 T 是对对象类型的右值引用,则结果是 xvalue;否则结果是纯右值。
所以这两个表达式都违反了这些约束。
【讨论】:
【参考方案2】:(long *) p 不应该是右值吗?
是的。
它们都是纯右值,因此,两个语句都是格式错误的:
[C++03: 5.4/1]:
表达式(T)
cast-expression 的结果是T
类型。如果T
是引用类型,则结果为左值,否则结果为右值。
[C++11: 5.4/1]:
表达式(T)
cast-expression 的结果是T
类型。如果T
是左值引用类型或对函数类型的右值引用,则结果是左值;如果T
是对对象类型的右值引用,则结果是xvalue;否则结果是prvalue。 [..]
GCC 4.8 rejects your "legal cast",但Visual Studio has an extension that accepts this(没有明显原因)。
【讨论】:
【参考方案3】:值转换的结果是一个右值。您不能分配给基本类型的右值。
换句话说,对于int a = 10;
,a
是int
类型的左值,但(long) a
是long
类型的临时右值,您不能分配给临时右值。指针也是如此。
【讨论】:
【参考方案4】:为什么你认为你的演员是合法的?我在两个演员表中都得到了error C2106: '=' : left operand must be l-value
。
这不应该是合法的。如果你真的想这样做,你必须像这样投射它:
(long*&)p = &l; // equivalent to *(long**)&p = &l
但除非你知道自己在做什么,否则不要这样做。
【讨论】:
当你知道自己在做什么时,你就不会那样做。以上是关于C++ 中的类型转换和指针类型转换的主要内容,如果未能解决你的问题,请参考以下文章