Подтвердить что ты не робот

Является `* - p` фактически законным (хорошо сформированным) в С++ 03

Мне интересно об этом примере кода:

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

Этот код действительно хорошо сформирован в С++ 03?

Мой аргумент заключается в том, что побочный эффект = завершается только после следующей точки последовательности, и поскольку мы получаем результат p=arr, код может быть не совсем сформирован, порядок между = и [].

Правильно ли я?

Поведение хорошо определено в C и в С++ 11. Этот код фактически получен из MySQL.

4b9b3361

Ответ 1

Конечно, он четко определен.

Не имеет значения, когда выполняется присвоение p=arr. Вы не оцениваете p[0], вы подписываете результат (p=arr), который является значением указателя, которое хранится в p. Независимо от того, сохранено ли оно еще, значение значения не изменяется, и значение известно независимо от того, было ли еще изменено p.

Аналогично, в *--p не существует поведения undefined. Было бы только поведение undefined, если бы к одной и той же переменной дважды обращались, включая хотя бы одну запись, между точками последовательности. Но p доступен только один раз, как часть --p. Он не читается снова (*p), оператор разыменования применяется к результату --p, который является четко определенным значением указателя.

Теперь это будет undefined поведение:

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

как и

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

Должно быть ясно, что результат преинкремента не считается неупорядоченным с записью, потому что утверждать, что существует раса, заключается в утверждении, что ++p никогда не может использоваться как rvalue, и в этом случае он должен автономно между точками последовательности, и вместо этого может использоваться пост-приращение. Не было бы никакого преимущества иметь как предварительный приращение, так и пост-инкремент на языке.