Является ли `* - p` действительно допустимым (корректным) в C ++ 03 - PullRequest
13 голосов
/ 13 января 2012

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

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

Действительно ли этот код правильно сформирован в C ++ 03?

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

Я прав?

Поведение хорошо определено в C и в C ++ 11. Этот код на самом деле является производным от MySQL.

1 Ответ

25 голосов
/ 13 января 2012

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

Неважно, когда присваивается 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;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...