* Temporary object omits constructor
@ 2008-05-21 17:14 Stefan Schulze Frielinghaus
2008-05-21 17:32 ` Joe Buck
0 siblings, 1 reply; 3+ messages in thread
From: Stefan Schulze Frielinghaus @ 2008-05-21 17:14 UTC (permalink / raw)
To: gcc
Hello all,
I just tried to easily show how many temporary objects get created in my
program. I created a test application like this one:
#include <iostream>
struct A {
static int c, d;
A() { ++c; }
~A() { ++d; }
void operator+=(const A&) { }
A operator+(const A&) { return *this; }
};
int A::c = 0;
int A::d = 0;
int main() {
A a, b, c;
a = b + c;
//a = b;
//a += c;
std::cout << A::c << " " << A::d << std::endl;
}
Whenever an object of class type A is created a counter is incremented.
So when I compile this application
(g++ -Wall -Wextra -O0 -ggdb2 -o test test.cpp) and run it I suspected
to get an output like this one: 4 1 (three objects plus one temporary
which gets destructed before std::cout).
But the actual result was: 3 1
The assembler output (i386) looks like this (without iostream etc):
gdb disas main:
0x080483d4 <main+0>: lea ecx,[esp+0x4]
0x080483d8 <main+4>: and esp,0xfffffff0
0x080483db <main+7>: push DWORD PTR [ecx-0x4]
0x080483de <main+10>: push ebp
0x080483df <main+11>: mov ebp,esp
0x080483e1 <main+13>: push ecx
0x080483e2 <main+14>: sub esp,0x24
0x080483e5 <main+17>: lea eax,[ebp-0x6]
0x080483e8 <main+20>: mov DWORD PTR [esp],eax
0x080483eb <main+23>: call 0x804845c <A>
0x080483f0 <main+28>: lea eax,[ebp-0x7]
0x080483f3 <main+31>: mov DWORD PTR [esp],eax
0x080483f6 <main+34>: call 0x804845c <A>
0x080483fb <main+39>: lea eax,[ebp-0x8]
0x080483fe <main+42>: mov DWORD PTR [esp],eax
0x08048401 <main+45>: call 0x804845c <A>
0x08048406 <main+50>: lea edx,[ebp-0x5]
0x08048409 <main+53>: lea eax,[ebp-0x8]
0x0804840c <main+56>: mov DWORD PTR [esp+0x8],eax
0x08048410 <main+60>: lea eax,[ebp-0x7]
0x08048413 <main+63>: mov DWORD PTR [esp+0x4],eax
0x08048417 <main+67>: mov DWORD PTR [esp],edx
0x0804841a <main+70>: call 0x8048480 <_ZN1AplERKS_>
0x0804841f <main+75>: sub esp,0x4
0x08048422 <main+78>: lea eax,[ebp-0x5]
0x08048425 <main+81>: mov DWORD PTR [esp],eax
0x08048428 <main+84>: call 0x804846e <~A>
0x0804842d <main+89>: lea eax,[ebp-0x8]
0x08048430 <main+92>: mov DWORD PTR [esp],eax
0x08048433 <main+95>: call 0x804846e <~A>
0x08048438 <main+100>: lea eax,[ebp-0x7]
0x0804843b <main+103>: mov DWORD PTR [esp],eax
0x0804843e <main+106>: call 0x804846e <~A>
0x08048443 <main+111>: lea eax,[ebp-0x6]
0x08048446 <main+114>: mov DWORD PTR [esp],eax
0x08048449 <main+117>: call 0x804846e <~A>
0x0804844e <main+122>: mov eax,0x0
0x08048453 <main+127>: mov ecx,DWORD PTR [ebp-0x4]
0x08048456 <main+130>: leave
0x08048457 <main+131>: lea esp,[ecx-0x4]
0x0804845a <main+134>: ret
Only three times the constructor is called but four times the destructor
and a magic call to "0x8048480 <_ZN1AplERKS_>".
Can someone explain these results?
Best regards
Stefan
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Temporary object omits constructor
2008-05-21 17:14 Temporary object omits constructor Stefan Schulze Frielinghaus
@ 2008-05-21 17:32 ` Joe Buck
2008-05-21 19:12 ` Stefan Schulze Frielinghaus
0 siblings, 1 reply; 3+ messages in thread
From: Joe Buck @ 2008-05-21 17:32 UTC (permalink / raw)
To: Stefan Schulze Frielinghaus; +Cc: gcc
On Wed, May 21, 2008 at 07:14:27PM +0200, Stefan Schulze Frielinghaus wrote:
> Hello all,
>
> I just tried to easily show how many temporary objects get created in my
> program. I created a test application like this one:
> #include <iostream>
>
> struct A {
> static int c, d;
> A() { ++c; }
> ~A() { ++d; }
> void operator+=(const A&) { }
> A operator+(const A&) { return *this; }
> };
You forgot to add
A::A(const A&) { ++c;}
The missing call is to the copy constructor. Since you didn't declare
one, the compiler inserts one, and it doesn't increment the counter.
Also, there are situations where a C++ compiler is allowed to eliminate
temporaries (even if this changes side effects that are invoked by
a copy constructor).
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Temporary object omits constructor
2008-05-21 17:32 ` Joe Buck
@ 2008-05-21 19:12 ` Stefan Schulze Frielinghaus
0 siblings, 0 replies; 3+ messages in thread
From: Stefan Schulze Frielinghaus @ 2008-05-21 19:12 UTC (permalink / raw)
To: Joe Buck; +Cc: gcc
On Wed, 2008-05-21 at 10:32 -0700, Joe Buck wrote:
> You forgot to add
>
> A::A(const A&) { ++c;}
>
> The missing call is to the copy constructor. Since you didn't declare
> one, the compiler inserts one, and it doesn't increment the counter.
Arghl your right. I removed the copy constructor two test cases before
and forget to add it again.
> Also, there are situations where a C++ compiler is allowed to eliminate
> temporaries (even if this changes side effects that are invoked by
> a copy constructor).
Yes your right. C++ Standard 12.8/15 says the same. But the object has
to be cv-unqualified and/or unnamed.
Thanks for your hint!
Best regards
Stefan
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-05-21 19:12 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-21 17:14 Temporary object omits constructor Stefan Schulze Frielinghaus
2008-05-21 17:32 ` Joe Buck
2008-05-21 19:12 ` Stefan Schulze Frielinghaus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).