【问题标题】:Casting and pointer casting in C++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

标签: c++ pointers casting lvalue rvalue


【解决方案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;aint 类型的左值,但(long) along 类型的临时右值,您不能分配给临时右值。指针也是如此。

      【讨论】:

        【解决方案4】:

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

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

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

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

        【讨论】:

        • 当你知道自己在做什么时,你就不会那样做。
        猜你喜欢
        • 2020-11-17
        • 1970-01-01
        • 2013-02-12
        • 1970-01-01
        • 2020-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-20
        相关资源
        最近更新 更多