Является ли эта самоинициализация действительной?

У меня есть этот вопрос, о котором я думал ранее, но решил, что ответить на него не так уж и просто.

int x = x + 1;
int main() {
  return x;
}

Мой вопрос заключается в том, определено ли поведение программы или нет, если оно вообще допустимо. Если он определен, известно ли значение x в main?


person Johannes Schaub - litb    schedule 22.07.2010    source источник
comment
Интересный. По крайней мере, GCC дает 1, даже с -std=c++98 -pedantic.   -  person Philipp    schedule 22.07.2010
comment
Компиляция с помощью MSVC9 (15.00.30729.01) дает 1.   -  person akira    schedule 22.07.2010
comment
На ум приходит Sequence Point en.wikipedia.org/wiki/Sequence_point   -  person    schedule 22.07.2010
comment
Зачем кому-то писать такой код? Во всяком случае, это может/спутает статический анализатор, который вы используете. Я бы счел такое поведение неопределенным, хотя многие компиляторы дают согласованный результат x=1.   -  person Schedler    schedule 22.07.2010
comment
@Schedler, я рекомендую против такого кода. Это чисто викторина, без какой-либо практической подготовки с моей стороны. :)   -  person Johannes Schaub - litb    schedule 22.07.2010
comment
Для случая constexpr недавно выяснилось, что это не совсем точно определено. Кажется, это подразумевает, что это так, но измененный язык все еще кажется неясным в этом вопросе. Я не знаю, как я пропустил этот вопрос, когда я проводил свое исследование ранее.   -  person Shafik Yaghmour    schedule 21.12.2015
comment
@шафик. Я бы не согласился, и, похоже, ваш ответ тоже. Он кажется хорошо определенным, но плохо сформированным.   -  person Johannes Schaub - litb    schedule 21.12.2015
comment
Что ж, этот случай не является постоянной инициализацией, о которой идет речь в отчете о дефекте. Я пропустил эту фразу Статическая инициализация должна выполняться до любой динамической инициализации. Что должно сделать это хорошо сформированным. Я не знаю, почему, когда я первоначально читал изменения, я думал, что это неясно для этого случая.   -  person Shafik Yaghmour    schedule 21.12.2015


Ответы (4)


Я почти уверен, что он определен, и x должен иметь значение 1. В §3.6.2/1 говорится: «Объекты со статической продолжительностью хранения (3.7.1) должны быть инициализированы нулями (8.5) до того, как произойдет любая другая инициализация. "

После этого, я думаю, все довольно просто.

person Jerry Coffin    schedule 22.07.2010
comment
Хм, удивительно, как тонко, но важно, прежде чем произойдет любая другая инициализация. является. - person GManNickG; 22.07.2010
comment
Я бы хотел, чтобы это было неопределенным, так как тогда мы могли бы сказать, не пишите такие вещи, трудно понять, что вы имеете в виду, не глядя в стандарт. - person Martin York; 22.07.2010
comment
@Martin York: У меня, например, нет проблем с тем, чтобы сказать, не делайте этого, о таком коде (и немало других вещей, которые определяют поведение). - person Jerry Coffin; 22.07.2010
comment
Отличный ответ! :-) - person dfrib; 06.11.2018

Мой вопрос заключается в том, определено ли поведение программы или нет, если оно вообще допустимо. Если он определен, известно ли значение x в main?

Этот код определенно не чистый, но для меня он должен работать предсказуемо.

int x помещает переменную в сегмент данных, который определен равным нулю при запуске программы. Перед main() вызываются статические инициализаторы. Для x это код x = x + 1. x = 0 + 1 = 1. Таким образом, main() вернет 1.

Код определенно будет работать непредсказуемым образом, если x будет локальной переменной, расположенной в стеке. Состояние стека, в отличие от сегмента данных, практически гарантированно содержит неопределенный мусор.

person Dummy00001    schedule 22.07.2010

Переменная «x» хранится в .bss, которая заполняется нулями при загрузке программы. Следовательно, значение «x» равно 0, когда программа загружается в память.

Затем перед вызовом main выполняется «x = x + 1».

Я не знаю, допустимо это или нет, но поведение не является неопределенным.

person Tomaka17    schedule 22.07.2010

Перед основным вызовом x должен быть инициализирован 0, поэтому его значение должно быть 1, когда вы вводите main, и вы возвращаете 1. Это определенное поведение.

person LostMohican    schedule 22.07.2010