我想知道这段代码:
int main()
{
char *p ;
char arr[100] = "Hello";
if ((p=arr)[0] == 'H') // do stuffs
}
这段代码实际上是否在C ++ 03中很好地形成了?
我的论点是=
的副作用仅在下一个序列点之后完成,因为我们正在访问p=arr
的结果,所以代码可能格式不正确,之间没有排序。 =
和[]
次操作。
我说错了吗?
在C和C ++ 11中很好地定义了这种行为。此代码实际上源自MySQL。
答案 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,在这种情况下它必须在序列点之间独立,并且可以使用后增量。在语言中同时使用预增量和后增量没有任何好处。