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

Заказ в инициализации в C, С++

Рассмотрим следующие инициализации:

/* C, C++ */
int a[] = { f(), g() };
struct { int x, y } foo = { f(), g() };

/* C++ */
struct goo { goo(int x, int y);  };

goo b = { f(), g() };
goo c { f(), g() };    /* C++11 */
goo d ( f(), g() );

Является ли порядок выполнения f() и g() в любой строке, заданной стандартами C и С++?

4b9b3361

Ответ 1

Во всех этих двух случаях

goo b = { f(), g() };
goo c { f(), g() };    /* C++11 */

порядок оценки определяется слева направо, и все побочные эффекты должны применяться перед следующим инициализатором.

Из С++ STandard

4 В списке инициализаторов списка с привязкой-инициализацией инициализатор-предложения, в том числе любые из результатов расширения пакета (14.5.3), оцениваются в том порядке, в котором они появляются. То есть, вычисление каждого значения и побочный эффект, связанный с данным Параметр инициализатор секвенирован перед каждым вычислением значения и побочный эффект, связанный с любым предложением инициализатора, которое следует за ним в список списков инициализаторов, разделенных запятыми.

Однако в C существует другое правило

Оценки выражений списка инициализации неопределенно упорядочены по отношению друг к другу и, следовательно, порядок, в котором происходят какие-либо побочные эффекты, не указывается.

Ответ 2

Является ли порядок выполнения f() и g() в любой строке, заданной стандартами C и С++?

В C, Нет. Они могут оцениваться в любом порядке.

C11 6.7.9 Инициализация

Оценки выражений списка инициализации неопределенно упорядочены с помощью друг другу и, следовательно, порядок, в котором происходят какие-либо побочные эффекты, не определено, 152).

В то время как С++ 11 говорит, что порядок оценки детерминирован.

8.5.4: 4 List-initialization

В списке инициализаторов списка с привязкой к инициализации предложения инициализатора, включая все, которые являются результатом разложений пакетов (14.5.3), , оцениваются в том порядке, в котором они отображаются, То есть, каждое вычисление значения и побочный эффект, связанный с заданным предложением инициализатора, секвенируются перед вычислением каждого значения и побочным эффектом, связанным с любым предложением инициализатора, которое следует за ним в разделенном запятыми списке списка инициализаторов.


152) В частности, порядок оценки не обязательно должен совпадать с порядком инициализации субобъекта.

Ответ 3

Нет, в C порядок оценки инициализаторов не указан:

(C11, 6.7.9p23) "Оценки выражений списка инициализации неопределенно секвенированы относительно друг друга и, следовательно, порядок, в котором происходят любые побочные эффекты, unspecified.152)"

152) В частности, порядок оценки не должен совпадать с порядком инициализации субобъекта.

В С++ поведение отличается, а инициализаторы оцениваются в том порядке, в котором они отображаются (С++ 11, 8.5.4p4).

Ответ 4

В С++ 11 соответствующая часть - это абзац 4 8.5.4 Инициализация списка

В списке инициализаторов списка с привязкой к инициализации предложения инициализатора, включая все, которые являются результатом разложений пакетов (14.5.3), , оцениваются в том порядке, в котором они отображаются, То есть, каждое вычисление значения и побочный эффект, связанный с заданным предложением инициализатора, секвенируются перед вычислением каждого значения и побочным эффектом, связанным с любым предложением инициализатора, которое следует за ним в разделенном запятыми списке списка инициализаторов. [Примечание. Это упорядочение оценки выполняется независимо от семантики инициализации; например, он применяется, когда элементы списка инициализатора интерпретируются как аргументы вызова конструктора, хотя обычно нет ограничений последовательности для аргументов вызова. - конечная нота]

Таким образом, порядок оценки слева направо.

Однако отметим, что, к сожалению, из-за bug, поскольку по крайней мере версия 4.7.0, GCC оценивает в обратном порядке, справа налево. Поэтому, если вы получите неожиданные результаты, это может быть причиной.