为什么这个演员的结果不是左撇子?

时间:2014-01-27 16:42:59

标签: c casting lvalue rvalue

我需要一些关于这种奇怪行为的建议 - 让我们有这个代码:

int ** p;

编译没有任何问题:

p++;

但是这个:

((int**)p)++;

给我这条错误消息:“error: lvalue required as increment operand”

我正在向p投射它已经存在的类型,没有任何变化,那么问题是什么?这是我遇到的问题的简化版本,当我试图编译一个旧版本时  版本gdb。所以我想,这样做有所改变。知道第二个例子有什么问题吗?

4 个答案:

答案 0 :(得分:6)

旧版本的gcc支持称为“左倾投射”的东西 - 如果你施放的是左值,结果是左值,可以这样对待。它的主要用途是允许您将指针增加一个与不同大小相对应的量:

int *p;
++(char *)p;  /* increment p by one byte, resulting in an unaligned pointer */

此扩展程序在gcc v3.0周围被弃用了一段时间,并在gcc v4.0中被删除

要在更新版本的gcc中执行相同的操作,您需要执行添加和赋值(而不是增量),将指针转换为添加类型并返回赋值:

p = (int *)((char *)p + 1);

请注意,在此之后尝试取消引用指针是未定义的行为,所以不要指望它做任何有用的事情。

答案 1 :(得分:4)

当您对表达式进行类型转换时,该表达式的结果是右值而不是左值。直观地说,一个类型转换说“如果它有其他类型,给我这个表达式将具有”,因此将变量类型转换为它自己的类型仍然会产生一个rvalue而不是一个左值。因此,将++运算符应用于类型转换的结果是不合法的,因为++需要左值并且您提供右值。

也就是说,原则上可以重新定义C语言,以便如果原始表达式是左值,则将值转换为自己的类型会产生左值,但为了简单起见和一致性,我认为语言设计者没有这样做。

希望这有帮助!

答案 2 :(得分:4)

  

为什么这个演员的结果不是左值?

我提请您注意C99规范第6.5.4节第4行脚注86,其中指出:

  

演员阵容不会产生左值。

你有一个演员。

结果不是左值。

++运算符需要左值。

因此您的程序是错误的。

答案 3 :(得分:3)

在C语言中,所有转换(包括显式转换)总是产生rvalues。没有例外。您将其转换为相同类型的事实并不能使其免于该规则。 (实际上,期望它做出如此不一致的异常会很奇怪。)

实际上,整个C语言的基本属性之一是它总是尽可能快地将lvalues转换为表达式中的rvalues。 C表达式中的Lvalues就像Mendeleev表中的第115个元素:它们通常寿命很短,很快就会腐烂到rvalues。这是C和C ++之间的主要区别,后者总是试图尽可能长地保留表达式中的左值(尽管在C ++中这个特定的强制转换也会产生一个右值)。