Что говорит стандарт?
От: saf_e  
Дата: 08.10.13 15:56
Оценка:
Разве с точки зрения стандарта тут возможен лик? Если да ткните, пожалуйста, в конкретное место.

foo(unique_ptr<X>(new X), unique_ptr<Y>(new Y));
Re: Что говорит стандарт?
От: jazzer Россия Skype: enerjazzer
Дата: 08.10.13 16:09
Оценка: 12 (1) +2
Здравствуйте, saf_e, Вы писали:

_>Разве с точки зрения стандарта тут возможен лик? Если да ткните, пожалуйста, в конкретное место.


_>
_>foo(unique_ptr<X>(new X), unique_ptr<Y>(new Y));
_>

Компилятор может это исполнить так:
X* x = new X;
Y* y = new Y;
unique_ptr<X> px(x);
unique_ptr<Y> py(y);
foo(px,py);

Валидно? Валидно — порядок вычисления аргументов функции неспецифицирован.
Где тут утечка может быть, видно? Если нет, подумай, что произойдет, если конструктор Y бросит исключение.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Что говорит стандарт?
От: saf_e  
Дата: 08.10.13 16:11
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, saf_e, Вы писали:


_>>Разве с точки зрения стандарта тут возможен лик? Если да ткните, пожалуйста, в конкретное место.


_>>
_>>foo(unique_ptr<X>(new X), unique_ptr<Y>(new Y));
_>>

J>Компилятор может это исполнить так:
J>
J>X* x = new X;
J>Y* y = new Y;
J>unique_ptr<X> px(x);
J>unique_ptr<Y> py(y);
J>foo(px,py);
J>

J>Валидно? Валидно — порядок вычисления аргументов функции неспецифицирован.
J>Где тут утечка может быть, видно? Если нет, подумай, что произойдет, если конструктор Y бросит исключение.

Мне казалось что стандарт рассматривает unique_ptr<X>(new X)как монолитное выражение и не бьет его. Собственно вот про этот момент и хотелось бы почитать.
Re: Что говорит стандарт?
От: Erop Россия  
Дата: 08.10.13 16:16
Оценка:
Здравствуйте, saf_e, Вы писали:

_>
_>foo(unique_ptr<X>(new X), unique_ptr<Y>(new Y));
_>



Порядок вычисления аргументов функции, так же, как и их частей не определён, компилятор, в целях оптимизации, может сделать, например, так:

{ 
    X* tmp1 = new X;
    Y* tmp2 = new Y; /* 2 */
    unique_ptr<X> tmp3( tmp1 );
    unique_ptr<Y> tmp4( tmp2 );
    foo( tmp3, tmp4 );
}
И если в /* 2 */ случится исключение, то tmp1 будет потерян...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Что говорит стандарт?
От: jazzer Россия Skype: enerjazzer
Дата: 08.10.13 16:27
Оценка:
Здравствуйте, saf_e, Вы писали:

_>Мне казалось что стандарт рассматривает unique_ptr<X>(new X)как монолитное выражение и не бьет его. Собственно вот про этот момент и хотелось бы почитать.


монолитное выражение в смысле сторонних эффектов (старые уже отработали, новые еще не начались) — это выражение между двумя точками следования (по терминологии С++03). А тут только одна точка следования — в конце полного выражения (где точка с запятой). Так что внутри можно тасовать все как угодно, в том числе и как я показал.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Что говорит стандарт?
От: saf_e  
Дата: 08.10.13 16:29
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, saf_e, Вы писали:


_>>Мне казалось что стандарт рассматривает unique_ptr<X>(new X)как монолитное выражение и не бьет его. Собственно вот про этот момент и хотелось бы почитать.


J>монолитное выражение в смысле сторонних эффектов (старые уже отработали, новые еще не начались) — это выражение между двумя точками следования (по терминологии С++03). А тут только одна точка следования — в конце полного выражения (где точка с запятой). Так что внутри можно тасовать все как угодно, в том числе и как я показал.


Эм, а разве запятые не являются точками следования? Т.е. выражение между запятыми должно быть вычисленно до другого.
Кстати, а что говорит новый стандарт, кажется точки следования отменили...
Re[5]: Что говорит стандарт?
От: jazzer Россия Skype: enerjazzer
Дата: 08.10.13 16:54
Оценка:
Здравствуйте, saf_e, Вы писали:

_>Здравствуйте, jazzer, Вы писали:


J>>Здравствуйте, saf_e, Вы писали:


_>>>Мне казалось что стандарт рассматривает unique_ptr<X>(new X)как монолитное выражение и не бьет его. Собственно вот про этот момент и хотелось бы почитать.


J>>монолитное выражение в смысле сторонних эффектов (старые уже отработали, новые еще не начались) — это выражение между двумя точками следования (по терминологии С++03). А тут только одна точка следования — в конце полного выражения (где точка с запятой). Так что внутри можно тасовать все как угодно, в том числе и как я показал.


_>Эм, а разве запятые не являются точками следования? Т.е. выражение между запятыми должно быть вычисленно до другого.

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

_>Кстати, а что говорит новый стандарт, кажется точки следования отменили...

Да, теперь там понятия типа happens before.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Что говорит стандарт?
От: __kot2  
Дата: 08.10.13 18:22
Оценка: 34 (2) +1
Здравствуйте, saf_e, Вы писали:
_>Разве с точки зрения стандарта тут возможен лик? Если да ткните, пожалуйста, в конкретное место.
_>
_>foo(unique_ptr<X>(new X), unique_ptr<Y>(new Y));
_>

да, как обьяснил jazzer. именно из-за этого, как я понимаю, ввели ф-ии типа make_unique и make_shared
Re[5]: Что говорит стандарт?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 08.10.13 18:35
Оценка:
Здравствуйте, saf_e, Вы писали:

J>>монолитное выражение в смысле сторонних эффектов (старые уже отработали, новые еще не начались) — это выражение между двумя точками следования (по терминологии С++03). А тут только одна точка следования — в конце полного выражения (где точка с запятой). Так что внутри можно тасовать все как угодно, в том числе и как я показал.


_>Эм, а разве запятые не являются точками следования? Т.е. выражение между запятыми должно быть вычисленно до другого.

_>Кстати, а что говорит новый стандарт, кажется точки следования отменили...

См. 1.9/13/14/15.
Более того, утечка возможна и в таком случае:
typedef void(*Fptr)(std::unique_ptr<X>);
Fptr lookup(int id);
//...
lookup(1)(std::unique_ptr<X>(new X));

если 'lookup' выбросит исключение, поскольку порядок вычисления 'new X' и 'lookup(1)' является unsequenced. Стандарт говорит только то, что эти подвыражения должны быть "sequenced before every expression or statement in the body of the called function". Относительный порядок вычислений не определен.
Re[3]: Что говорит стандарт?
От: Evgeny.Panasyuk Россия  
Дата: 08.10.13 19:26
Оценка: 1 (1)
Здравствуйте, saf_e, Вы писали:

_>Мне казалось что стандарт рассматривает unique_ptr<X>(new X)как монолитное выражение и не бьет его. Собственно вот про этот момент и хотелось бы почитать.


Например у Саттера: раз, два.
Re: Что говорит стандарт?
От: saf_e  
Дата: 09.10.13 06:36
Оценка:
всем спасибо
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.