Определение двух переменных: Is «Тип a (arg), b (arg);»полностью эквивалентно "Type a (arg); Type b (arg);"? - PullRequest
9 голосов
/ 07 декабря 2011

Предположим, я хочу определить две переменные класса {Type}.Конструктор принимает 1 аргумент.Являются ли следующие два способа полностью эквивалентными (скомпилированы в один и тот же объектный код)?

Type a(arg), b(arg);

и

Type a(arg);
Type b(arg);

Этот вопрос возникает после того, как я прочитал страницу, рассказывающую о безопасности исключений ---http://www.gotw.ca/gotw/056.htm Существует руководство «Выполнять каждое распределение ресурсов (например, новое) в своем собственном кодовом выражении, которое немедленно передает новый ресурс объекту менеджера».Он приводит пример: Следующий фрагмент кода безопасен

auto_ptr<T> t1( new T );
auto_ptr<T> t2( new T );
f( t1, t2 );

Но строка ниже небезопасна

f( auto_ptr<T>( new T ), auto_ptr<T>( new T ) );

Итак, как насчет

auto_ptr<T> t1( new T ), t2( new T );
f( t1, t2 );

I?Мы просмотрели документ стандарта языка C ++, но не нашли ничего, что указывало бы на эту проблему.

Чтобы запутать воду, как насчет

shared_ptr<T> t1( new T );
shared_ptr<T> t2( t1 );

и

shared_ptr<T> t1( new T ), t2( t1 );

Ответы [ 3 ]

7 голосов
/ 07 декабря 2011

Да, они эквивалентны. См. C ++ 11, 8/3:

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

Сноска 97 довольно длинная, в ней говорится, что T D1, D2, ... Dn; "обычно" эквивалентен T D1; T D2; ... T Dn;, за исключением случаев, когда значение T в последующих декларациях зависит от того, что вы делаете. Приведены два примера:

struct S {};
S S, T; // is not equivalent to:
S S; S T;

auto i = 1, j = 2.0; // is not equivalent to:
auto i = 1; auto j = 2.0;

Но в обоих случаях одной из альтернатив является ошибка, так что это не различие, которое приведет к тому, что вам придется запускать отладчик.

В любом случае, да, auto_ptr<T> t1( new T ), t2( new T ); так же безопасен, как и auto_ptr<T> t1( new T ); auto_ptr<T> t2( new T );

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

2 голосов
/ 07 декабря 2011

Да, по определению: http://www.open -std.org / jtc1 / sc22 / wg21 / docs / wp / html / oct97 / decl.html

Each init-declarator in a declaration is analyzed separately as if it was in a
declaration by itself.
2 голосов
/ 07 декабря 2011

Компилятор может вычислять оба значения new T до того, как он создаст auto_ptr с, создавая параметры для вызова функции .Если в середине этой последовательности возникнет исключение, вы можете получить утечки памяти.

Что касается того, что происходит в объявлении переменной , проверьте этот предыдущий вопрос: Запятаяв списке переменных точка последовательности?

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