Инициализация временными объектами
От: iterator it Украина  
Дата: 09.09.11 10:13
Оценка:
Здравствуйте!

Что говорится в стандарте о инициализации временными объектами?

Пусть есть определенный класс A.

class A
{
public:
A(int){};
A(const A&){};
A& operator=(const A&){};
}

void f(A)
{
}

Казалось бы вызов A a = A(5) должен привести к конструированию и последующему вызову конструктора копирования, но этого не происходит.

Вызывается только конструктор A(int).

то же самое происходит при вызове
f(A(5)); // no copy constructor

Как это понимать? implementation defined? или это описано в стандарте?
временные объекты инициализация
Re: Инициализация временными объектами
От: sysenter  
Дата: 09.09.11 10:30
Оценка:
Здравствуйте, iterator it, Вы писали:

II>Как это понимать? implementation defined? или это описано в стандарте?


Оптимизация компилятора возможно
Re: Инициализация временными объектами
От: Alexander Poluektov Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 09.09.11 10:39
Оценка:
Здравствуйте, iterator it, Вы писали:

II>Казалось бы вызов A a = A(5) должен привести к конструированию и последующему вызову конструктора копирования, но этого не происходит.


II>Вызывается только конструктор A(int).


II>то же самое происходит при вызове

II>f(A(5)); // no copy constructor

II>Как это понимать? implementation defined? или это описано в стандарте?


Компилятор имеет право "выкидывать" копии конструктора копирования в таких случаях -- даже если конструктор копирования и, соответственно, деструктор, имеют побочные эффекты.

Замечу, что g++, начиная как минимум с 4.1 проделывают такую оптимизацию даже без включенных оптимизаций ("в дебаге"), и ее нужно иногда специально давить, чтобы отлавливать некоторые косяки в коде.
Re[2]: Инициализация временными объектами
От: iterator it Украина  
Дата: 09.09.11 10:41
Оценка:
Здравствуйте, sysenter, Вы писали:
S>Оптимизация компилятора возможно

Это работает и в Debug режиме и на microsoft компиляторах (msvs2010) и на open source (g++).
Разве что стандарт де факто.

Вопрос все еще открыт.
Re[2]: Инициализация временными объектами
От: iterator it Украина  
Дата: 09.09.11 10:45
Оценка:
Это право компилятора выкидывать лишние копирующие конструкторы как нибудь регламентировано в стандарте ANSI C++ или это все таки implementation defined который уже стал стандартом де-факто?
Спасибо.

Здравствуйте, Alexander Poluektov, Вы писали:
AP>Компилятор имеет право "выкидывать" копии конструктора копирования в таких случаях -- даже если
конструктор копирования и, соответственно, деструктор, имеют побочные эффекты.
Re[3]: Инициализация временными объектами
От: sysenter  
Дата: 09.09.11 10:45
Оценка:
Здравствуйте, iterator it, Вы писали:

II>Разве что стандарт де факто.

II>Вопрос все еще открыт.

Уже ответили, оптимизация компилятора, должны оба конструктора вызваться, один вызов компилятор выкидывает. На GCC при любой -Ox такое поведение
Re[2]: 12.8/15
От: Alexander Poluektov Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 09.09.11 10:46
Оценка:
Здравствуйте, iterator it, Вы писали:

II>> или это описано в стандарте?


15 When certain criteria are met, an implementation is allowed to omit the copy construction of a class object,
even if the copy constructor and/or destructor for the object have side effects. In such cases, the implemen-
tation treats the source and target of the omitted copy operation as simply two different ways of referring to
the same object, and the destruction of that object occurs at the later of the times when the two objects
would have been destroyed without the optimization.
This elision of copy operations is permitted in the following circumstances (which may be combined to eliminate multiple copies):
— in a return statement in a function with a class return type, when the expression is the name of a
non-volatile automatic object with the same cv-unqualified type as the function return type, the copy
operation can be omitted by constructing the automatic object directly into the function’s return value
— when a temporary class object that has not been bound to a reference (12.2) would be copied to a class
object with the same cv-unqualified type, the copy operation can be omitted by constructing the tempo-
rary object directly into the target of the omitted copy

Re[3]: Инициализация временными объектами
От: Alexander Poluektov Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 09.09.11 10:47
Оценка:
Здравствуйте, iterator it, Вы писали:

II>Это право компилятора выкидывать лишние копирующие конструкторы как нибудь регламентировано в стандарте ANSI C++ или это все таки implementation defined который уже стал стандартом де-факто?

II>Спасибо.

Это гарантируется пунктом 12.8/15 of Holy C++ Standard, 2003 edition.
Re: Инициализация временными объектами
От: Кодт Россия  
Дата: 09.09.11 10:58
Оценка: +1
Здравствуйте, iterator it, Вы писали:

II>Казалось бы вызов A a = A(5) должен привести к конструированию и последующему вызову конструктора копирования, но этого не происходит.


Самое печальное для разработчика — в том, что компилятор может выкинуть, а может и не выкинуть промежуточные конструкторы копирования при инициализации и при возврате значения из функции (RVO, NRVO).
И это — по стандарту.

Поэтому надо закладывать побочные эффекты так, чтобы они не зависели от количества промежуточных копий.
Перекуём баги на фичи!
Re: Инициализация временными объектами
От: Erop Россия  
Дата: 09.09.11 12:18
Оценка:
Здравствуйте, iterator it, Вы писали:

II>Как это понимать? implementation defined? или это описано в стандарте?


Это С++03

Да, к тому, что уже тут сказали, надо добавить, что в случае такой инициализации компилятор ОБЯЗАН проверять наличие и доступность конструктора копии, даже если он его выбрасывает из когда...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Инициализация временными объектами
От: Alexander Poluektov Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 09.09.11 12:38
Оценка:
Здравствуйте, Erop, Вы писали:

E>Да, к тому, что уже тут сказали, надо добавить, что в случае такой инициализации компилятор ОБЯЗАН проверять наличие и доступность конструктора копии, даже если он его выбрасывает из когда...


Однако не проверяет
http://stackoverflow.com/questions/5552981/rvo-nrvo-and-public-undefined-copy-constructor
Re[3]: Инициализация временными объектами
От: Erop Россия  
Дата: 09.09.11 13:05
Оценка:
Здравствуйте, Alexander Poluektov, Вы писали:

AP>Однако не проверяет

AP>http://stackoverflow.com/questions/5552981/rvo-nrvo-and-public-undefined-copy-constructor

1) Речь шла про инициализацию копированием, а не про RVO.
2) VC, например, долгое время не проверял...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.