当铸造指针有增量运算符时会发生什么?

时间:2011-03-19 21:52:07

标签: c++ c pointers compiler-construction programming-languages

例如:

int x[100];
void *p;

x[0] = 0x12345678;
x[1] = 0xfacecafe;
x[3] = 0xdeadbeef;

p = x;
((int *) p) ++ ;

printf("The value = 0x%08x", *(int*)p);

编译上面的代码会在使用++运算符的行上生成一个左值所需的错误。

5 个答案:

答案 0 :(得分:18)

强制转换创建一个int *类型的临时指针。您不能增加临时值,因为它不表示存储结果的位置。

在C和C ++标准中,(int *)p右值,它大致意味着只能出现在赋值右侧的表达式。

另一方面,

p左值,这意味着它可以有效地出现在作业的左侧。只能增加左值。

答案 1 :(得分:3)

表达式((int *) p)处理存储在变量p中的指针是指向int的指针。如果要将变量本身视为指向int变量的指针(然后递增它),请使用引用强制转换:

((int *&) p) ++ ;

答案 2 :(得分:1)

您可以使用

获得预期的结果
p = (int*)p + 1;

在取消引用指向p的指针上使用增量运算符,这是一个左值,也有效:

(*(int**)&p)++;

但是,后者不可移植,因为(void*)p可能与(int*)p的表示形式不同。

答案 3 :(得分:1)

感谢larsmans指向正确的方向。

我冒昧地深入研究这个问题。因此,供将来参考,根据C99标准的第6.5.2.4和6.5.4节(http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf):

  

6.5.2.4后缀增量和减量运算符

     

约束

     

后缀增量的操作数   或减少运营商应具备的   合格或不合格的真实或   指针类型,应该是可修改的   左值
..
..
  6.5.4铸造操作员
  ..
  ..
  [脚注] 89)演员   不产生左值。因此,一个演员   到合格的类型有相同的   作为一个演员的效果不合格   该类型的版本。

注意:这仅适用于C. C ++可能以不同方式处理强制转换。

答案 4 :(得分:0)

Rvalue表达式((int *) p)创建int*类型的临时变量,但无法应用运算符++

++需要左值作为其操作数。

由于@FredOverflow提及lvaluesrvalues与作业几乎没有关系。

数组是左值,但它们无法分配,因为它们是不可修改的。 std::string("Prasoon")是一个右值表达式,它仍然可以出现在赋值运算符的左侧,因为我们被允许在临时值上调用成员函数(在这种情况下为operator =)。