default constructor
От: kvas Россия  
Дата: 20.05.04 07:29
Оценка:
Есть код:


#include <iostream>

struct Foo
{
    //Foo() {};
    ~Foo() { std::cout << "Destructor was called" << std::endl; }
};

void main()
{
    Foo &r = Foo();
}


Исполнение этого кода, скомпилированного VC 7.1, приводит к выводу двух строк "Destructor was called".
А если раскомментировать явное определение default constructor, то одной строки.
Почему так?
Re: default constructor
От: Lorenzo_LAMAS  
Дата: 20.05.04 07:33
Оценка:
Не стоит гадать что и почему — эта программа неверна и не должна компилироваться, ты привязываешь неконстантную ссылку к r-value. Что там делает ВЦ — уже не важно.
Of course, the code must be complete enough to compile and link.
Re[2]: default constructor
От: Denwer Россия  
Дата: 20.05.04 07:51
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Не стоит гадать что и почему — эта программа неверна и не должна компилироваться, ты привязываешь неконстантную ссылку к r-value. Что там делает ВЦ — уже не важно.

Если написать так, то ситуация не изменится. С чего бы это?
const Foo &r = Foo();


Разве это противоречит станларту?

ИМХО: Глючок компилятора.
Re[2]: default constructor
От: kvas Россия  
Дата: 20.05.04 07:53
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Не стоит гадать что и почему — эта программа неверна и не должна компилироваться, ты привязываешь неконстантную ссылку к r-value. Что там делает ВЦ — уже не важно.


Пусть так.
Но если заменить

Foo &r = Foo();

на

const Foo &r = Foo();


результат не меняется.
?
Re[3]: default constructor
От: Lorenzo_LAMAS  
Дата: 20.05.04 08:06
Оценка:
D>Разве это противоречит станларту?
D>ИМХО: Глючок компилятора.

Когда r-value привязывается к константной ссылке, может вызываться конструктор копий. Может в этом дело? Или дважды разрушается один и тот же объект?
Of course, the code must be complete enough to compile and link.
Re[3]: default constructor
От: kvas Россия  
Дата: 20.05.04 08:07
Оценка:
Здравствуйте, Denwer, Вы писали:

D>ИМХО: Глючок компилятора.


В VC6 аналогично.
По какой-то причине в одном случае создается дополнительный временный объект, а в другом нет.
Может быть это вовсе и не несответствие стандарту, а проведенная компилятором оптимизация.
Re[4]: default constructor
От: Denwer Россия  
Дата: 20.05.04 08:13
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

D>>Разве это противоречит станларту?

D>>ИМХО: Глючок компилятора.

L_L>Когда r-value привязывается к константной ссылке, может вызываться конструктор копий. Может в этом дело? Или дважды разрушается один и тот же объект?


У интела 8.0 все впорядке кстати.
Re[5]: default constructor
От: Lorenzo_LAMAS  
Дата: 20.05.04 08:15
Оценка:
D>У интела 8.0 все впорядке кстати.

Так плевать на интел. У VC то как? Смотри, кстати, 8.5.3 / 5 , стр. 148, то место, где 93)
Of course, the code must be complete enough to compile and link.
Re[4]: default constructor
От: kvas Россия  
Дата: 20.05.04 08:16
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Когда r-value привязывается к константной ссылке, может вызываться конструктор копий. Может в этом дело? Или дважды разрушается один и тот же объект?


Допустим конструктор копий может вызывать, а может и не вызываться. Очевидно, что причиной желания не вызывать его лишний раз является съэкономить на времени исполнения.
Если так то почему же тогда в случае сгенерированного компилятором конструктора оптимизация не проводится. Он ведь в точности такой-же.
Re[5]: default constructor
От: Lorenzo_LAMAS  
Дата: 20.05.04 08:20
Оценка:
K>Допустим конструктор копий может вызывать, а может и не вызываться. Очевидно, что причиной желания не вызывать его лишний раз является съэкономить на времени исполнения.
K>Если так то почему же тогда в случае сгенерированного компилятором конструктора оптимизация не проводится. Он ведь в точности такой-же.

Он не точно такой же, он ТРИВИАЛЬНЫЙ. А если ты его явно определил то он уже не тривиальный. Кроме того, попробуй сделай деструктор виртуальным или добавь в класс виртуальную функцию, конструктор (неявно сгенерированный компилятором) тоже будет уже не тривиальным и лишних объектов не будет.

А по какому принципу вижуал решает, когда нужно копировать, а когда нет — это ты в микрософт напиши лучше.
Of course, the code must be complete enough to compile and link.
Re: default constructor
От: Demay  
Дата: 20.05.04 08:52
Оценка:
Здравствуйте, kvas, Вы писали:

K>Есть код:



K>
K>#include <iostream>

K>struct Foo
K>{
K>    //Foo() {};
K>    ~Foo() { std::cout << "Destructor was called" << std::endl; }
K>};

K>void main()
K>{
K><b>    Foo &r = Foo(); //<- если Foo() не определено, такая запись создает анонимный экземпляр</b>
K>}
K>


K>Исполнение этого кода, скомпилированного VC 7.1, приводит к выводу двух строк "Destructor was called".

K>А если раскомментировать явное определение default constructor, то одной строки.
K>Почему так?

Когда отсвутствует явное определение default constructor, запись Foo(), приводит к созданию анонимного экземпляра объекта, адрес которого и присваивается ссылке.
По выходу из main вызывается dtor анонимного экземпляра объекта, а затем dtor ссылки.
Причем оба вызова разрушают один и тот же объект, в этом легко убедится, если вывести в std::cout, this удаляемого объекта.
В частности GCC, выдает на эту строку ошибку, а IntelC++8.0, почему-то кушает, но и анонимный экземпляра объекта не создает. Видимо это фича от VC++.
К сожалению не обнаружил, подход какого компилятора правильно трактует такую ситуацию по стандарту.
Re[3]: default constructor
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 20.05.04 08:58
Оценка:
Здравствуйте, Denwer, Вы писали:

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


D>Если написать так, то ситуация не изменится. С чего бы это?

D>
D>const Foo &r = Foo();
D>


D>Разве это противоречит станларту?


D>ИМХО: Глючок компилятора.


Нет никакого глюка.

В первом случае создаётся ещё один временный объект — вот и 2 вызова деструктора: 1-ый для Foo() (вызывается когда завершается инициализация ссылки), 2-ой для временного объекта созданного компилятором и связанного с сылкой (вызывается когда уничтожается ссылка).
Во втором случае компилятор непосредственно связывает временный объект, созданный вызовом Foo() с сылкой и удерживает его до уничтожения ссылки — деструктор вызывается один раз.

По стандарту компилятор может поступать и так и эдак, причём делает это он на своё усмотрение.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[2]: default constructor
От: Lorenzo_LAMAS  
Дата: 20.05.04 09:13
Оценка:
Во-первых, программа неверная, привязка r-value к неконстантной ссылке — фича микрософтовского компилятора.

Во — вторых.
Не знаю, чем ты компил, но в VC 7.1 деструкторы вызываются для двух разных объектов, причем время вызова такое — для временного объекта по окончанию полного выражения, как и положено, для копии — после выхода из мэйн.
Of course, the code must be complete enough to compile and link.
Re[2]: default constructor
От: kvas Россия  
Дата: 20.05.04 09:14
Оценка:
Здравствуйте, Demay, Вы писали:

D>Когда отсвутствует явное определение default constructor, запись Foo(), приводит к созданию анонимного экземпляра объекта, адрес которого и присваивается ссылке.

D>По выходу из main вызывается dtor анонимного экземпляра объекта, а затем dtor ссылки.
D>Причем оба вызова разрушают один и тот же объект, в этом легко убедится, если вывести в std::cout, this удаляемого объекта.
D>В частности GCC, выдает на эту строку ошибку, а IntelC++8.0, почему-то кушает, но и анонимный экземпляра объекта не создает. Видимо это фича от VC++.
D>К сожалению не обнаружил, подход какого компилятора правильно трактует такую ситуацию по стандарту.

Ну gcc выдает ошибку видимо потому что я, как мне любезно напомнил Lorenzo_LAMAS, пытался инициализировать неконстантную ссылку rvalue.

А насчет одинакового значения this, то у меня они выводятся разные (VC 7.1).
Re[4]: default constructor
От: jazzer Россия Skype: enerjazzer
Дата: 20.05.04 09:46
Оценка:
Здравствуйте, Mr. None, Вы писали:

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


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


D>>Если написать так, то ситуация не изменится. С чего бы это?

D>>
D>>const Foo &r = Foo();
D>>


D>>Разве это противоречит станларту?


D>>ИМХО: Глючок компилятора.


MN>Нет никакого глюка.


MN>В первом случае создаётся ещё один временный объект — вот и 2 вызова деструктора: 1-ый для Foo() (вызывается когда завершается инициализация ссылки), 2-ой для временного объекта созданного компилятором и связанного с сылкой (вызывается когда уничтожается ссылка).

MN>Во втором случае компилятор непосредственно связывает временный объект, созданный вызовом Foo() с сылкой и удерживает его до уничтожения ссылки — деструктор вызывается один раз.

MN>По стандарту компилятор может поступать и так и эдак, причём делает это он на своё усмотрение.


А можно ссылочку?
Что-то я не помню разрешения плодить временные объекты
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[5]: default constructor
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 20.05.04 10:01
Оценка:
Здравствуйте, jazzer, Вы писали:

MN>>Нет никакого глюка.


MN>>В первом случае создаётся ещё один временный объект — вот и 2 вызова деструктора: 1-ый для Foo() (вызывается когда завершается инициализация ссылки), 2-ой для временного объекта созданного компилятором и связанного с сылкой (вызывается когда уничтожается ссылка).

MN>>Во втором случае компилятор непосредственно связывает временный объект, созданный вызовом Foo() с сылкой и удерживает его до уничтожения ссылки — деструктор вызывается один раз.

MN>>По стандарту компилятор может поступать и так и эдак, причём делает это он на своё усмотрение.


J>А можно ссылочку?

J>Что-то я не помню разрешения плодить временные объекты

Стандарт — 8.5.3/4, 12.2/1, 12.2/5
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[6]: default constructor
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 20.05.04 10:10
Оценка:
Здравствуйте, Mr. None, Вы писали:


MN>Стандарт — 8.5.3/4, 12.2/1, 12.2/5


8.5.3/4:

If the initializer expression is an rvalue, ..., the reference is bound in one of the following ways (the choice is implementation-defined):
— The reference is bound to the object represented by the rvalue.
— A temporary ... is created, and constructor is called to copy the entire rvalue object into the temporary.

Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[5]: default constructor
От: Lorenzo_LAMAS  
Дата: 20.05.04 10:14
Оценка:
J>Что-то я не помню разрешения плодить временные объекты
8.5.3/5 (стр 148)
Of course, the code must be complete enough to compile and link.
Re[6]: default constructor
От: Denwer Россия  
Дата: 20.05.04 10:29
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

D>>У интела 8.0 все впорядке кстати.


L_L>Так плевать на интел. У VC то как? Смотри, кстати, 8.5.3 / 5 , стр. 148, то место, где 93)


Я собственно не веню компилятор в том что он вызывает 2 раза деструктор, а не один, проблема то в другом.
Почему от того, есть ли конструктор или нет, зависит его поведение, и потом так сильно. Малоли что я могу делать
в своей программе в этом деструкторе, а потом добавлю конструктор и ее поведение поменяется коренным образом.
Как то это не правельно.
Re: default constructor
От: Fox Россия  
Дата: 20.05.04 10:38
Оценка:
Здравствуйте, kvas, Вы писали:

K>Есть код:



K>
K>#include <iostream>

K>struct Foo
K>{
K>    //Foo() {};
K>    ~Foo() { std::cout << "Destructor was called" << std::endl; }
K>};

K>void main()
K>{
K>    Foo &r = Foo();
K>}
K>


K>Исполнение этого кода, скомпилированного VC 7.1, приводит к выводу двух строк "Destructor was called".

K>А если раскомментировать явное определение default constructor, то одной строки.
K>Почему так?

Хотите еще веселее ???
Попробуйте деструктор сделать виртуальным
Будет один раз срабатывать.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.