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

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

int ** p; 

这编译没有任何麻烦:

 p++; 

但是这个:

 ((int**)p)++; 

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

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

旧版本的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); 

请注意,在此之后尝试取消引用指针是未定义的行为,因此不要指望它执行任何有用的操作。

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

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

希望这可以帮助!

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

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

演员阵容不会产生左值。

你有一个演员。

结果不是左值。

++运算符需要左值。

因此,您的程序是一个错误。

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

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