От: | remark | http://www.1024cores.net/ | |
Дата: | 29.09.06 10:15 | ||
Оценка: | 107 (9) -1 |
struct AAA
{
AAA()
{
std::cout << __FUNCTION__ << std::endl;
}
~AAA()
{
std::cout << __FUNCTION__ << std::endl;
}
};
void deleterAAA(AAA* aaa)
{
// Сюда попадаем раньше, чем в aaa()
std::cout << __FUNCTION__ << std::endl;
delete aaa;
}
typedef boost::shared_ptr<AAA> AAAPtr;
AAAPtr getAAAPtr()
{
std::cout << __FUNCTION__ << std::endl;
return AAAPtr(new AAA, deleterAAA);
}
AAA* getAAA(AAAPtr a)
{
std::cout << __FUNCTION__ << std::endl;
return a.get();
// Здесь вызывается deleterAAA !!! :maniac:
}
void aaa(AAA* a)
{
std::cout << __FUNCTION__ << std::endl;
// Здесь объект, на который указывает a, уже разрушен :maniac:
}
int main()
{
std::cout << __FUNCTION__ << std::endl;
// По идее здесь getAAAPtr() возвращает временный объект типа AAAPtr,
// который должен дожить до конца вызова функции aaa(),
// и который должен "держать" обеъкт AAA,
// т.е. в aaa() должен попасть "живой" объект AAA
aaa(getAAA(getAAAPtr()));
}
main
getAAAPtr
AAA::AAA
getAAA
deleterAAA
AAA::~AAA
aaa
Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.
There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression.
The first context is when a default constructor is called to initialize an element of an array...
The second context is when a reference is bound to a temporary...
A full-expression is an expression that is not a subexpression of another expression. If a language construct |
is defined to produce an implicit call of a function, a use of the language construct is considered to be an |
expression for the purposes of this definition. Conversions applied to the result of an expression in order to |
satisfy the requirements of the language construct in which the expression appears are also considered to be |
part of the full-expression. [Example:
struct S { |
S(int i): I(i) { } |
int& v() { return I; } |
private: |
int I; |
}; |
S s1(1); //full-expression is call of S::S(int) |
S s2 = 2; //full-expression is call of S::S(int) |
void f() { |
if (S(3).v()) // full-expression includes lvalue-to-rvalue and |
// int to bool conversions, performed before |
// temporary is deleted at end of full-expression |
{ } |
} |
—end example]
От: | _nn_ | www.nemerleweb.com | |
Дата: | 29.09.06 11:53 | ||
Оценка: |
typedef int AAA;
typedef boost::shared_ptr<AAA> AAAPtr;
AAAPtr f()
{
return AAAPtr(new int)); // 5. создается объект
} // 6. Вызов конструктора копирования, объект жив. (компилятор оптимизирует его обычно)
AAA* g()
{
return f().get(); // 2. вызов f
// 7. boost::shared_ptr<AAA>::get
// 8. Объект умирает после вызова get, так как область видимости его ограниченна ";".
} // 9. Возврат мусора.
int main()
{
AAA* p = g(); // 1. вызов g
}
От: | remark | http://www.1024cores.net/ | |
Дата: | 29.09.06 11:59 | ||
Оценка: |
__>typedef int AAA;
__>typedef boost::shared_ptr<AAA> AAAPtr;
__>AAAPtr f()
__>{
__> return AAAPtr(new int)); // 5. создается объект
__>} // 6. Вызов конструктора копирования, объект жив. (компилятор оптимизирует его обычно)
__>AAA* g()
__>{
__> return f().get(); // 2. вызов f
__> // 7. boost::shared_ptr<AAA>::get
__> // 8. Объект умирает после вызова get, так как область видимости его ограниченна ";".
__>} // 9. Возврат мусора.
__>int main()
__>{
__> AAA* p = g(); // 1. вызов g
__>}
__>
От: | Vain | google.ru | |
Дата: | 29.09.06 12:58 | ||
Оценка: |
От: | remark | http://www.1024cores.net/ | |
Дата: | 29.09.06 14:14 | ||
Оценка: |
От: | Константин Л. | ||
Дата: | 29.09.06 14:21 | ||
Оценка: | -1 |
От: | Vain | google.ru | |
Дата: | 29.09.06 17:14 | ||
Оценка: |
AA* getAAA(AAAPtr& a)
{
От: | remark | http://www.1024cores.net/ | |
Дата: | 30.09.06 05:50 | ||
Оценка: |
От: | remark | http://www.1024cores.net/ | |
Дата: | 30.09.06 05:55 | ||
Оценка: | +2 |
V>AA* getAAA(AAAPtr& a)
V>{
V>
От: | night beast | ||
Дата: | 30.09.06 06:14 | ||
Оценка: |
От: | Константин Л. | ||
Дата: | 30.09.06 09:41 | ||
Оценка: |
От: | Vain | google.ru | |
Дата: | 30.09.06 11:58 | ||
Оценка: |
От: | remark | http://www.1024cores.net/ | |
Дата: | 02.10.06 07:25 | ||
Оценка: |
f1(f2());
От: | remark | http://www.1024cores.net/ | |
Дата: | 02.10.06 07:38 | ||
Оценка: | 7 (1) |
f1(f2());
std::string getFilename()
{
return "1.txt";
}
const char* extractStr(std::string s)
{
return s.c_str();
}
int main()
{
printf("%s", extractStr(getFilename()));
}
const char* extractStr(std::string s)
const char* extractStr(std::string& s)
const char* extractStr(const std::string& s)
От: | Константин Л. | ||
Дата: | 02.10.06 08:51 | ||
Оценка: |
От: | night beast | ||
Дата: | 02.10.06 08:58 | ||
Оценка: |
R>std::string getFilename()
R>{
R> return "1.txt";
R>}
R>const char* extractStr(std::string s)
R>{
R> return s.c_str();
R>}
R>int main()
R>{
R> printf("%s", extractStr(getFilename()));
R>}
R>
От: | crable | ||
Дата: | 02.10.06 10:02 | ||
Оценка: |
[snip]
R>AAAPtr getAAAPtr()
R>{
R> std::cout << __FUNCTION__ << std::endl;
R> return AAAPtr(new AAA, deleterAAA); //a) создается временный AAAPtr, число ссылок = 1
R>} // b) при выходе, конструируется AAAPtr из временного объекта созданного в a)
// затем временный объект созданный в a) уничтожается, число ссылок = 1.
R>AAA* getAAA(AAAPtr a) //c) конструируется AAAPtr из временного объекта созданного в b)
// затем временный объект созданный в b) уничтожается, число ссылок = 1.
R>{
R> std::cout << __FUNCTION__ << std::endl;
R> return a.get();
R> // Здесь вызывается deleterAAA !!! :maniac:
R>} // при выходе временный объект созданный в c) уничтожается, число ссылок = 0, вызывается deleterAAA
R>От: | remark | http://www.1024cores.net/ | |
Дата: | 02.10.06 10:10 | ||
Оценка: |
R>>std::string getFilename()
R>>{
R>> return "1.txt";
R>>}
R>>const char* extractStr(std::string s)
R>>{
R>> return s.c_str();
R>>}
R>>int main()
R>>{
R>> printf("%s", extractStr(getFilename()));
R>>}
R>>
От: | remark | http://www.1024cores.net/ | |
Дата: | 02.10.06 10:13 | ||
Оценка: |
C>[snip]
R>>AAAPtr getAAAPtr()
R>>{
R>> std::cout << __FUNCTION__ << std::endl;
R>> return AAAPtr(new AAA, deleterAAA); //a) создается временный AAAPtr, число ссылок = 1
R>>} // b) при выходе, конструируется AAAPtr из временного объекта созданного в a)
C>// затем временный объект созданный в a) уничтожается, число ссылок = 1.
R>>AAA* getAAA(AAAPtr a) //c) конструируется AAAPtr из временного объекта созданного в b)
C>// затем временный объект созданный в b) уничтожается, число ссылок = 1.
R>>{
R>> std::cout << __FUNCTION__ << std::endl;
R>> return a.get();
R>> // Здесь вызывается deleterAAA !!! :maniac:
R>>} // при выходе временный объект созданный в c) уничтожается, число ссылок = 0, вызывается deleterAAA
R>>От: | night beast | ||
Дата: | 02.10.06 10:18 | ||
Оценка: |
C>[snip]
R>>AAA* getAAA(AAAPtr a) //c) конструируется AAAPtr из временного объекта созданного в b)
C>// затем временный объект созданный в b) уничтожается, число ссылок = 1.
на основаниии чего временный объект должен уничтожаться именно здесь?
R>>
От: | Lorenzo_LAMAS | ||
Дата: | 02.10.06 10:24 | ||
Оценка: |
От: | remark | http://www.1024cores.net/ | |
Дата: | 02.10.06 11:06 | ||
Оценка: | +1 |
От: | elcste | ||
Дата: | 02.10.06 14:58 | ||
Оценка: | 8 (1) |
От: | remark | http://www.1024cores.net/ | |
Дата: | 02.10.06 15:17 | ||
Оценка: |
От: | Lorenzo_LAMAS | ||
Дата: | 03.10.06 09:18 | ||
Оценка: |
От: | Lorenzo_LAMAS | ||
Дата: | 03.10.06 09:20 | ||
Оценка: |
От: | Кодт | ||
Дата: | 03.10.06 10:01 | ||
Оценка: | 14 (2) |
#include <iostream>
using std::cout;
using std::endl;
int refcount = 0;
struct share
{
share()
{
++refcount;
cout << this << " : " << __FUNCTION__ << " : " << refcount << endl;
}
share(const share&)
{
++refcount;
cout << this << " : " << __FUNCTION__ << " : " << refcount << endl;
}
~share()
{
--refcount;
cout << this << " : " << __FUNCTION__ << " : " << refcount << endl;
}
int get() const
{
cout << this << " : " << __FUNCTION__ << " : " << refcount << endl;
return 0;
}
};
share make()
{
cout << __FUNCTION__ << " : " << refcount << endl;
return share();
}
int unfold(share tmp)
{
cout << __FUNCTION__ << " : " << refcount << endl;
return tmp.get();
}
void accept(int)
{
cout << __FUNCTION__ << " : " << refcount << endl;
}
int main()
{
cout << __FUNCTION__ << " : " << refcount << endl;
accept(unfold(make()));
cout << __FUNCTION__ << " : " << refcount << endl;
return 0;
}
main : 0
make : 0 -- ещё нет объектов...
0012FE84 : share::share : 1 -- вот мы его создали в make() - return share()
unfold : 1 -- вот он уже как параметр unfold
0012FE84 : share::get : 1 -- пока что жив...
0012FE84 : share::~share : 0 -- вот мы вышли из unfold
accept : 0 -- и к моменту входа в accept все умерли
main : 0
От: | remark | http://www.1024cores.net/ | |
Дата: | 03.10.06 10:02 | ||
Оценка: |
От: | elcste | ||
Дата: | 03.10.06 11:06 | ||
Оценка: | 8 (1) |
при игнорировании 12.8/15The lifetime of a parameter ends when the function in which it is defined returns.
In such cases, the implementation 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.
От: | night beast | ||
Дата: | 03.10.06 14:29 | ||
Оценка: |
От: | remark | http://www.1024cores.net/ | |
Дата: | 03.10.06 14:39 | ||
Оценка: |
От: | night beast | ||
Дата: | 03.10.06 14:46 | ||
Оценка: |
От: | night beast | ||
Дата: | 04.10.06 05:56 | ||
Оценка: |
От: | Кодт | ||
Дата: | 04.10.06 08:31 | ||
Оценка: | 32 (5) |
#include <iostream>
using namespace std;
struct Data
{
int m_refcount;
unsigned m_signature;
Data() : m_refcount(0), m_signature(0x900DDA7A) { cout<<"CONSTRUCT"<<endl; }
~Data() { cout<<"DESTROY"<<endl; m_signature=0xDEADFACE; }
void addref() { ++m_refcount; }
void release() { if(--m_refcount==0) delete this; }
};
ostream& operator<<(ostream& ost, const Data& data)
{
return ost<<"Data"<<"(ref="<<data.m_refcount<<",sig="<<hex<<data.m_signature<<dec<<")";
}
struct Ptr;
ostream& operator<<(ostream& ost, const Ptr& );
static int ids = 0;
struct Ptr
{
int m_id; // to see lifetime of particular Ptrs
Data* m_data;
explicit Ptr(Data* data) : m_id(++ids), m_data(data)
{
m_data->addref();
cout<<"ctor "<<*this<<endl;
}
Ptr(const Ptr& src) : m_id(++ids), m_data(src.m_data)
{
m_data->addref();
cout<<"cctor "<<*this<<endl;
}
~Ptr()
{
cout<<"dtor "<<*this<<endl;
m_data->release();
}
Data* get() const
{
cout<<"get "<<*this<<endl;
return m_data;
}
};
ostream& operator<<(ostream& ost, const Ptr& ptr)
{
return ost<<"Ptr #"<<ptr.m_id<<" ("<<*ptr.m_data<<")";
}
void accept(Data* data)
{
cout<<"accept "<<*data<<endl;
}
Data* pass(Ptr ptr)
{
cout<<"pass ("<<ptr<<")"<<endl;
return ptr.get();
}
Ptr rvo_make()
{
cout<<"rvo_make"<<endl;
return Ptr(new Data());
}
Ptr nrvo_make()
{
cout<<"nrvo_make"<<endl;
Ptr ptr(new Data());
cout<<"nrvo_make completed"<<endl;
return ptr;
}
Ptr nonopt_make()
{
cout<<"nonopt_make"<<endl;
if(rand() % 2)
{
Ptr ptr(new Data());
cout<<"nonopt_make completed, v1"<<endl;
return ptr;
}
else
{
Ptr ptr(new Data());
cout<<"nonopt_make completed, v2"<<endl;
return ptr;
}
}
int main()
{
cout<<"---tmp---"<<endl;
ids=0;
accept(pass(Ptr(new Data())));
cout<<"---rvo---"<<endl;
ids=0;
accept(pass(rvo_make()));
cout<<"---nrvo---"<<endl;
ids=0;
accept(pass(nrvo_make()));
cout<<"---nonopt---"<<endl;
ids=0;
accept(pass(nonopt_make()));
}
Действие | debug | release |
---|---|---|
TMP | CONSTRUCT ctor Ptr #1 (Data(ref=1,sig=900dda7a)) pass (Ptr #1 (Data(ref=1,sig=900dda7a))) get Ptr #1 (Data(ref=1,sig=900dda7a)) dtor Ptr #1 (Data(ref=1,sig=900dda7a)) DESTROY accept Data(ref=3473816,sig=3530c0) | CONSTRUCT ctor Ptr #1 (Data(ref=1,sig=900dda7a)) pass (Ptr #1 (Data(ref=1,sig=900dda7a))) get Ptr #1 (Data(ref=1,sig=900dda7a)) dtor Ptr #1 (Data(ref=1,sig=900dda7a)) DESTROY accept Data(ref=3473816,sig=3530c0) |
RVO | rvo_make CONSTRUCT ctor Ptr #1 (Data(ref=1,sig=900dda7a)) pass (Ptr #1 (Data(ref=1,sig=900dda7a))) get Ptr #1 (Data(ref=1,sig=900dda7a)) dtor Ptr #1 (Data(ref=1,sig=900dda7a)) DESTROY accept Data(ref=3473816,sig=355050) | rvo_make CONSTRUCT ctor Ptr #1 (Data(ref=1,sig=900dda7a)) pass (Ptr #1 (Data(ref=1,sig=900dda7a))) get Ptr #1 (Data(ref=1,sig=900dda7a)) dtor Ptr #1 (Data(ref=1,sig=900dda7a)) DESTROY accept Data(ref=3473816,sig=355050) |
NRVO | nrvo_make CONSTRUCT ctor Ptr #1 (Data(ref=1,sig=900dda7a)) nrvo_make completed cctor Ptr #2 (Data(ref=2,sig=900dda7a)) dtor Ptr #1 (Data(ref=2,sig=900dda7a)) pass (Ptr #2 (Data(ref=1,sig=900dda7a))) get Ptr #2 (Data(ref=1,sig=900dda7a)) dtor Ptr #2 (Data(ref=1,sig=900dda7a)) DESTROY accept Data(ref=3473816,sig=355050) | nrvo_make CONSTRUCT ctor Ptr #1 (Data(ref=1,sig=900dda7a)) nrvo_make completed pass (Ptr #1 (Data(ref=1,sig=900dda7a))) get Ptr #1 (Data(ref=1,sig=900dda7a)) dtor Ptr #1 (Data(ref=1,sig=900dda7a)) DESTROY accept Data(ref=3473816,sig=3530c0) |
NonOpt | nonopt_make CONSTRUCT ctor Ptr #1 (Data(ref=1,sig=900dda7a)) nonopt_make completed, v1 cctor Ptr #2 (Data(ref=2,sig=900dda7a)) dtor Ptr #1 (Data(ref=2,sig=900dda7a)) pass (Ptr #2 (Data(ref=1,sig=900dda7a))) get Ptr #2 (Data(ref=1,sig=900dda7a)) dtor Ptr #2 (Data(ref=1,sig=900dda7a)) DESTROY accept Data(ref=3473816,sig=355050) | nonopt_make CONSTRUCT ctor Ptr #1 (Data(ref=1,sig=900dda7a)) nonopt_make completed, v1 cctor Ptr #2 (Data(ref=2,sig=900dda7a)) dtor Ptr #1 (Data(ref=2,sig=900dda7a)) pass (Ptr #2 (Data(ref=1,sig=900dda7a))) get Ptr #2 (Data(ref=1,sig=900dda7a)) dtor Ptr #2 (Data(ref=1,sig=900dda7a)) DESTROY accept Data(ref=3473816,sig=355050) |
От: | Кодт | ||
Дата: | 04.10.06 09:31 | ||
Оценка: | +1 |
От: | remark | http://www.1024cores.net/ | |
Дата: | 04.10.06 09:56 | ||
Оценка: |
От: | Вадим Никулин | Здесь | |
Дата: | 06.10.06 05:17 | ||
Оценка: |
От: | Ovl | ||
Дата: | 06.10.06 09:25 | ||
Оценка: |
От: | Кодт | ||
Дата: | 06.10.06 11:04 | ||
Оценка: | 1 (1) |
Ptr* volatile p;
Ptr nonopt_make()
{
Ptr ptr(new Data());
p = &ptr;
return *p;
}
От: | remark | http://www.1024cores.net/ | |
Дата: | 08.10.06 10:52 | ||
Оценка: | 37 (2) |
От: | night beast | ||
Дата: | 08.10.06 14:12 | ||
Оценка: |
От: | remark | http://www.1024cores.net/ | |
Дата: | 08.10.06 14:42 | ||
Оценка: |
От: | Vain | google.ru | |
Дата: | 08.10.06 15:28 | ||
Оценка: |
От: | remark | http://www.1024cores.net/ | |
Дата: | 08.10.06 16:43 | ||
Оценка: | +1 |
От: | Кодт | ||
Дата: | 09.10.06 09:02 | ||
Оценка: |
От: | remark | http://www.1024cores.net/ | |
Дата: | 09.10.06 09:05 | ||
Оценка: |
От: | Ovl | ||
Дата: | 09.10.06 09:12 | ||
Оценка: |
От: | night beast | ||
Дата: | 09.10.06 09:13 | ||
Оценка: |
От: | kan | ||
Дата: | 09.10.06 10:07 | ||
Оценка: |
Page Not Found
The content that you requested cannot be found or you do not have permission to view it.
От: | night beast | ||
Дата: | 09.10.06 10:18 | ||
Оценка: |
kan>kan>Page Not Found
kan>The content that you requested cannot be found or you do not have permission to view it.
От: | kan | ||
Дата: | 09.10.06 10:32 | ||
Оценка: |
От: | remark | http://www.1024cores.net/ | |
Дата: | 09.10.06 10:36 | ||
Оценка: |
От: | remark | http://www.1024cores.net/ | |
Дата: | 11.10.06 10:48 | ||
Оценка: | 54 (1) |
Comments Entered by Microsoft on 10/10/2006 at 12:09 PM
Hi: unfortunately as this bug is not specific to Visual C++ SP1 (particularly it is not a regression in behavior from Visual C++ 2005) we will not be able to fix it in this Service Pack. But we have added the bug to our list of issues for the next release of Visual C++.
Jonathan Caves
Visual C++ Compiler Team
От: | remark | http://www.1024cores.net/ | |
Дата: | 12.10.06 04:23 | ||
Оценка: |
R>Comments Entered by Microsoft on 10/10/2006 at 12:09 PM
R>Hi: unfortunately as this bug is not specific to Visual C++ SP1 (particularly it is not a regression in behavior from Visual C++ 2005) we will not be able to fix it in this Service Pack. But we have added the bug to our list of issues for the next release of Visual C++.
R>Jonathan Caves
R>Visual C++ Compiler Team
От: | night beast | ||
Дата: | 12.10.06 05:07 | ||
Оценка: |