2013-06-29 3 views
4

Скажем, у меня есть этот класс:порядок вычисления аргументов конструктору

struct A 
{ 
    A(int, int, int) {} 
}; 

и я инициализировать его следующим образом:

A{ a(), b(), c() }; 

Где функции a(), b() и c() возвращают int. Должно ли a() вызывать до b() и b() до c()?

Я озадачен следующим пунктом от стандарта (8.5.4 [dcl.init.list] p4):

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

В соответствии с цитатой функции будут вызываться в порядке их появления, но когда я проверил это с моим компилятором (g ++ - 4.8.1), он не выполнялся. Я что-то неправильно понял?

+0

Спасибо, принимая список инициализации в конструкторе, как представляется, обходной путь. – user1095108

ответ

6

Это bug in GCC (спасибо Casey за ссылку). В этом пункте вы процитировали относится в целом к ​​списку инициализации, где термины определены довольно четко в пункте 8.5.4/1:

Список инициализация является инициализация объекта или ссылки из рамно-INIT -list. Такой инициализатор называется списком инициализатора, и разделенные запятые инициализатор-пункты списка называется элементами списка инициализатора.

Нет причин полагать, что это должно применяться только к вызову конструктора списка инициализаторов.Кроме того, в записке в пункте вы цитируемого разъясняет, что:

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

+4

Это [GCC ошибка 51253] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253) , – Casey

+0

@ Casey: Хорошо, я не знал об этом. Спасибо за ссылку! –

2

Будьте осторожны, с чем вы сталкиваетесь. Цитата, которую вы цитируете, насколько я вижу, содержит только для списков инициализаторов . Используемая функция: Единая идентификация. Это необходимо для списков инициализаторов, но я сомневаюсь, что это для равномерной инициализации.

+2

В цитате упоминаются вызовы конструктора. Считаете ли вы, что цитата относится только к конструкторам, принимающим списки инициализаторов? – user1095108

+0

Uniform инициализации является неформальным термином для грамматической конструкции, известной как рамно-Init-лист. Это отличается от типа 'std :: initializer_list'. – Potatoswatter

+0

И цитируемый текст начинается с «В инициализатора-лист в рамно-Init-лист» – celtschk

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