我需要一些关于这种奇怪行为的建议 - 让我们有这个代码:
int ** p;
编译没有任何问题:
p++;
但是这个:
((int**)p)++;
给我这条错误消息:“error: lvalue required as increment operand”
。
我正在向p
投射它已经存在的类型,没有任何变化,那么问题是什么?这是我遇到的问题的简化版本,当我试图编译一个旧版本时
版本gdb
。所以我想,这样做有所改变。知道第二个例子有什么问题吗?
答案 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 ++中这个特定的强制转换也会产生一个右值)。