[interfacekit] Re: oddish?
- From: Ingo Weinhold <bonefish@xxxxxxxxxxxxxxx>
- To: interfacekit@xxxxxxxxxxxxx
- Date: Wed, 25 Feb 2004 00:10:44 +0100
On 2004-02-16 at 17:28:58 [+0100], Marcus Overhagen wrote:
> > > On Mon, 16 Feb 2004, Adi Oanca wrote:
> > >
> > > > int main()
> > > > {
> > > > [...]
> > > > lay->Invalidate(BRect(225,10,350,400));//BRegion(lay->Bounds()));
> > > > [...]
> > > > }
> > > >
> >
> > As Ingo pointed out, this is perfectly valid C++. I'd like to point out
> > that this the above is an example of something you should try to avoid.
> > Not because of the BRect->BRegion thing, but because some compilers
> > (like ours) have an issue with the scope of temporaries that are used as
> > arguments. This only happens sometimes and I'm not really sure under
> > what circumstances this turns into an error. (runtime error! :-( ) But
> > it
> > is safer to do the following:
> >
> > BRect rect(225,10,350,400);
> > lay->Invalidate(rect);
>
> According to Stroustrup, this is complicated.
> Explicit calling of the constructor of an Object that
> is used to initialize a const reference is allowed.
>
> Like in this example:
>
> void foo(const BString &);
>
> foo(BString("test"));
>
> As long as a temporary object is bound to a const reference,
> it won't be destroyed.
>
> But if the temporary opject is only used inside an expression,
> it will be destroyed at the end of the expression. Example:
>
> const char * str = BString("test).String();
>
> At the end of the "BString("test).String()" expression, the
> temporary BString object is destroyed, and the pointer
> that was returned by String() is no longer valid, as the
> object is missing.
>
> The same applies if such a temporary object is used as
> a function parameter, as long as the temporary object
> is not bound to a const reference parameter.
>
> Here the object is only temporary, and since it is used in a
> full expression, it will be destroyed after the end of the full
> expression. Consider this example:
>
> void bar(const char *);
>
> bar(BString("test").String());
>
> A temporary BString object is created, initalized with "test".
> Then a pointer to the (copy) of the string inside the BString
> object is returned by the String() function, and pushed on the
> stack. Now the expression is evaluated, and the temporary
> BString object is destroyed. Now the function bar() is executed,
> using the pointer that is on the stack, but no longer valid since
> the temporary object was already destroyed.
I don't believe this is true. AFAIK temporary objects are not destroyed at
the end of an expression, but at the end of a statement; that is in your
example after bar() returned. Attached is a little program that executes two
tests, which demonstrate that behavior. The second test is of particular
interest, since it also shows how buggy our gcc is -- the B destructor is
invoked twice on the same object. mwcc does it correctly though, destroying
B after A.
CU, Ingo
#include <stdio.h>
class A {
public:
A()
{
printf("A::A()\n");
}
~A()
{
printf("A::~A()\n");
}
const char* m()
{
return "Hello World!";
}
};
class B {
public:
B()
{
printf("B::B()\n");
}
~B()
{
printf("B::~B()\n");
}
const char* m()
{
return "Hello World!";
}
};
const char*
bar(const char* a)
{
printf("bar(%s)\n", a);
return a;
}
A
foo(B b)
{
printf("foo()\n");
return A();
}
int
main()
{
printf("test 1\n");
printf("------\n");
bar(A().m());
printf("\ntest 2\n");
printf("------\n");
bar(foo(B()).m());
return 0;
}
- Follow-Ups:
- [interfacekit] Re: oddish?
- From: Andrew Bachmann
- References:
- [interfacekit] Re: oddish?
- From: Marcus Overhagen
Other related posts:
- » [interfacekit] oddish?
- » [interfacekit] Re: oddish?
- » [interfacekit] Re: oddish?
- » [interfacekit] Re: oddish?
- » [interfacekit] Re: oddish?
- » [interfacekit] Re: oddish?
- » [interfacekit] Re: oddish?
- [interfacekit] Re: oddish?
- From: Andrew Bachmann
- [interfacekit] Re: oddish?
- From: Marcus Overhagen