在* C ++ 03中,`* - p`实际上是合法的(格式良好)

时间:2012-01-13 03:32:33

标签: c++ undefined-behavior language-lawyer c++03

我想知道这段代码:

int main()
{
   char *p ;
   char arr[100] = "Hello";
   if ((p=arr)[0] == 'H') // do stuffs
}

这段代码实际上是否在C ++ 03中很好地形成了?

我的论点是=的副作用仅在下一个序列点之后完成,因为我们正在访问p=arr的结果,所以代码可能格式不正确,之间没有排序。 =[]次操作。

我说错了吗?

在C和C ++ 11中很好地定义了这种行为。此代码实际上源自MySQL。

1 个答案:

答案 0 :(得分:25)

当然它的定义很明确。

分配p=arr何时发生并不重要。您没有评估p[0],您正在订阅(p=arr)的结果,这是存储在p中的指针值。无论它是否已存储,都不会更改该值,无论p是否已被修改,该值都是已知的。

同样,在*--p中,没有未定义的行为。如果在序列点之间访问相同的变量两次(包括至少一次写入),则只有未定义的行为。但p仅作为--p的一部分访问过一次。它不会再次读取(*p),解除引用运算符将​​应用于--p的结果,这是一个明确定义的指针值。

现在,这将是未定义的行为:

void* a;
void* p = &a;
reinterpret_cast<void**>(p = &p)[0] = 0;

就像

一样
int *pi = new int[5];
int i = **&++pi;

应该很清楚,preincrement的结果不是与write无序的读取,因为断言有一个种族是断言++p永远不能用作rvalue,在这种情况下它必须在序列点之间独立,并且可以使用后增量。在语言中同时使用预增量和后增量没有任何好处。