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

Pav*_*vel 5 c casting rvalue lvalue

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

int ** p;
Run Code Online (Sandbox Code Playgroud)

编译没有任何麻烦:

p++;
Run Code Online (Sandbox Code Playgroud)

但是这个:

((int**)p)++;
Run Code Online (Sandbox Code Playgroud)

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

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

Chr*_*odd 6

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

int *p;
++(char *)p;  /* increment p by one byte, resulting in an unaligned pointer */
Run Code Online (Sandbox Code Playgroud)

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

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

p = (int *)((char *)p + 1);
Run Code Online (Sandbox Code Playgroud)

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


tem*_*def 5

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

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

希望这可以帮助!

  • @KeithThompson 我已经看到广泛用于这个术语的术语“类型转换”,“转换”只是它的一个短期术语。[维基百科](http://en.wikipedia.org/wiki/Type_conversion) 似乎也支持这一点。 (6认同)
  • 该术语是“强制转换”,而不是“类型转换”。(类型转换是发生在演员身上的事情。) (3认同)
  • 术语“类型转换”在 K&R2 或 ISO C 标准中没有出现过(并且在那篇 Wikipedia 文章中只出现过一次,该文章随后将显式 C 类型转换称为“类型转换”)。 (2认同)

AnT*_*AnT 5

在 C 语言中,所有转换(包括显式转换)总是产生右值。没有例外。您将其强制转换为相同类型的事实并不意味着它可以免受该规则的约束。(实际上,期望它产生如此不一致的异常是很奇怪的。)

事实上,整个 C 语言的基本属性之一是它总是尽快将表达式中的左值转换为右值。C 表达式中的左值就像门捷列夫表的第 115 个元素:它们的寿命通常非常短,很快就会衰减为右值。这是 C 和 C++ 之间的主要区别,后者总是尝试尽可能长时间地保留表达式中的左值(尽管在 C++ 中,这种特定的强制转换也会产生右值)。


Eri*_*ert 5

为什么这个转换的结果不是左值?

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

强制转换不会产生左值。

你有一个演员阵容。

结果不是左值。

++运算符需要一个左值。

因此你的程序是一个错误。