А>Я ожидал, что данная прога выведет результат — 2, т.е. сработает 2-ой конструктор. Но под Линуксом (gcc 3.2) она выдает 1. Компилируя сей код с помощью VS2005 тоже получается 1. Но если в VS отключить оптимизации, то результат — 2.
Вопрос в том, что вперед работает...
Список инициализации или вызов функции...
Очевидно, оптимизация влияет на этот порядок...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
А>Я ожидал, что данная прога выведет результат — 2, т.е. сработает 2-ой конструктор. Но под Линуксом (gcc 3.2) она выдает 1. Компилируя сей код с помощью VS2005 тоже получается 1. Но если в VS отключить оптимизации, то результат — 2.
А>Подскажите пожалуйста, что здесь не так?
Cтандарту разрешается выполнять RETURN VALUE OPTIMIZATION, то есть комплилятор может опустить создание временного объекта, а подставить на его место адрес инициализируемого объекта, то есть вместо myVar, компилятор сгенерирует код инициализирующий mainVar.
Copy-конструктор - подскажите, что не так?
От:
Аноним
Дата:
25.05.07 08:56
Оценка:
Добрый день!
Имеется следующий код:
#include <iostream>
using namespace std;
class MyClass
{
int value;
public:
MyClass(): value(1) {}
MyClass(const MyClass& cl): value(2) {}
void print() { cout << value << endl; }
};
MyClass func()
{
MyClass myVar;
return myVar;
}
int main(void)
{
MyClass mainVar = func();
mainVar.print();
return 0;
}
Я ожидал, что данная прога выведет результат — 2, т.е. сработает 2-ой конструктор. Но под Линуксом (gcc 3.2) она выдает 1. Компилируя сей код с помощью VS2005 тоже получается 1. Но если в VS отключить оптимизации, то результат — 2.
скорее всего компилятор видит что функция возвращает обьект и не видит смысл делать переприсвоение много раз
так что скорее всего ты работаешь всего с одним обьектом и копи конструктор даже и не вызывался
Да истранный конструктор у тебя вроде он должен был копировать — а так создал другой обьект
Спасибо
АШ>Cтандарту разрешается выполнять RETURN VALUE OPTIMIZATION, то есть комплилятор может опустить создание временного объекта, а подставить на его место адрес инициализируемого объекта, то есть вместо myVar, компилятор сгенерирует код инициализирующий mainVar.
И тут еще и NAMED VALUE RETURN OPTIMIZATION
Of course, the code must be complete enough to compile and link.
Тут у него поведение копирующего конструктора отличается собственно от копирования.
А если так и задумано кодером? Это только для не переопределенного конструктора копирования такие вольности компилера даже приветствуются...
Здравствуйте, hVostt, Вы писали:
V>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>Компилятору позволено осуществлять оптимизацию, выбрасывая лишнее копирование объекта.
V>Тут у него поведение копирующего конструктора отличается собственно от копирования. V>А если так и задумано кодером?
А вот не надо такого задумывать и проблем не будет. Т.е. не надо полагаться на то, что конструктор копирования будет обязательно вызван.
Of course, the code must be complete enough to compile and link.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>>Компилятору позволено осуществлять оптимизацию, выбрасывая лишнее копирование объекта. V>>Тут у него поведение копирующего конструктора отличается собственно от копирования. V>>А если так и задумано кодером? L_L>А вот не надо такого задумывать и проблем не будет. Т.е. не надо полагаться на то, что конструктор копирования будет обязательно вызван.
Странно как-то, ведь предусмотренно переопределение copy-ctor, для конкретного указания кодером того как надо копировать объект. Правда в данном случае и я затрудняюсь придумать чтоже умного тут можно сделать. А может как раз на автора снизошло озарение и он понел что, а тут какие-то условности.. Толи компилер вызовет определенныю кодером операцию, толи забьет на него " в целях оптимизации"..
Большое спасибо за ответы! Получается, что в copy-конструкторах смысла особого нету, если у оптимизатора есть официальное право избегать лишнего (на его взгляд) копирования объектов. Т.е. лучше их вообще всеми силами избегать? Согласен, что пример выше несколько притянут за уши, но ситуация, когда в принципе укладывающийся в спецификацию языка код вызывает разные результаты в зависимости от конкретного компайлера, несколько пугает
Здравствуйте, hVostt, Вы писали:
V>Странно как-то, ведь предусмотренно переопределение copy-ctor, для конкретного указания кодером того как надо копировать объект. Правда в данном случае и я затрудняюсь придумать чтоже умного тут можно сделать. А может как раз на автора снизошло озарение и он понел что, а тут какие-то условности.. Толи компилер вызовет определенныю кодером операцию, толи забьет на него " в целях оптимизации"..
В стандарте четко описано, что можно оптимизировать, а что нельзя.
Здравствуйте, Aleksis, Вы писали:
A>День добрый еще раз, аноним это я
A>Большое спасибо за ответы! Получается, что в copy-конструкторах смысла особого нету, если у оптимизатора есть официальное право избегать лишнего (на его взгляд) копирования объектов. Т.е. лучше их вообще всеми силами избегать? Согласен, что пример выше несколько притянут за уши, но ситуация, когда в принципе укладывающийся в спецификацию языка код вызывает разные результаты в зависимости от конкретного компайлера, несколько пугает
Избегать их нет необходимости, если они нужны.
Другой вопрос в том, что, как уже говорилось, стандарт позволяет компилятору предполагать, что конструктор копирования копирует объекты, а не занимается самодеятельностью. Чтобы код работал всегда так, как надо, надо всего лишь, чтобы программа соответствовала представлениям компилятора о ней