2013-03-12 1 views
13

Заголовок вопроса говорит все: есть ли объявления формы int a = 0, b = a имеют неопределенное поведение?Имеет ли `int a = 0, b = a` неопределенное поведение?

+2

Следующий вопрос будет тогда, делает ли такую ​​строку кода смысл в любом реальном сценарии? Есть ли причина, по которой вы должны писать это, а не 'int a = 0; int b = 0; '? – Lundin

+0

@ Lundin Когда значение 'a' является результатом функции, которую вы не хотите выполнять дважды, это мой случай. Мне нужно две копии этого значения: один для вывода и тот, который мне нужно изменить, выполняя некоторые другие вычисления. –

+0

Возможный дубликат [Является ли запятая в списке переменных точкой последовательности?] (Http://stackoverflow.com/questions/6414030/is-the-comma-in-a-variable-list-a-sequence-point) и [Является ли порядок определения в списке инициализированных переменных неопределенным?] (http://stackoverflow.com/questions/12729962/is-the-order-of-assingment-in-a-list-of-initialized-variables -undefined? lq = 1) ... –

ответ

12

Нет, это четко определено. Это декларация с двумя деклараторами, a и b. Каждый декларатор имеет инициализатор.

Каждый INIT-описатель в объявлении анализируется отдельно, как если бы это было в объявлении сам по себе.

То есть, линия трактуется как:

int a = 0; 
int b = a; 
+4

«проанализировано отдельно», похоже, ничего не говорит о последовательности в заявлении о выполнении. Есть ли более сильное указание об этом в стандарте? –

+0

Чтобы ответить на мой собственный комментарий, я думаю, вам нужно процитировать 1.9/14 об оценке секвенсированных полных выражений перед оценкой последующих полных выражений. См. Комментарий к http://stackoverflow.com/a/6414247/19563. –

8

Нет, нет Неопределенное поведение.

в соответствии с пунктом 8/3 из C++ 11 стандарта на:

Каждый INIT-описатель в объявлении анализируется отдельно, как если бы это было в объявлении сам по себе

Кроме того, сноски 97 определяет:

декларация с несколькими declarators обычно эквивалентна соответствующей последовательности деклараций каждый с одним объявлением . То есть

T D1, D2, ... Dn;

обычно (*) эквивалентно

T D1; T D2; ... T Dn;

Это означает, что a инициализирован, а затем b инициализируется и принимает значение a. Также обратите внимание, что даже если это не так, было quite a long debate on SO по поводу того, будет ли это или не будет UB, и был достигнут некоторый консенсус относительно того, что это не является UB.


(*): Как объясняется Olaf Dietsche в комментариях, в ситуации, когда эта эквивалентность делает не захват упомянуты позже в том же примечании.

+0

Сноски не являются нормативными в стандарте ИСО, поэтому они ничего не указывают, они всего лишь информативный текст. – Lundin

+0

В дополнение к тому, что сказал Лундин, слово «обычно» не дает мне никаких теплых нечетких чувств о гарантиях последовательности. – IronMensan

+1

@ Lundin: Сноски не являются нормативными, это правильно. Но они часто указывают, что вы могли бы вывести из Стандарта более сложные формальные выводы. Я сам не смог выполнить эти выводы, но я думал, что это может быть релевантной ссылкой, по крайней мере, как декларация о намерениях. –

 Смежные вопросы

  • Нет связанных вопросов^_^