On Wed, May 11, 2011 at 10:15 PM, Matt Fischer <mattfische...@gmail.com> wrote:
> I've noticed some behavior with g++ that seems strange to me.  I don't
> know if there's some technicality in the C++ standard that requires
> this, or if it's just a limitation to the optimization code, but it
> seemed strange so I thought I'd see if anybody could shed more light
> on it.
>
> Here's a test program that illustrates the behavior:
>
> struct Foo {
>    char buf[256];
>    Foo() {} // suppress automatically-generated constructor code for clarity
>    ~Foo() {}
> };
>
> void func0(const Foo &);
> void func1(const Foo &);
> void func2(const Foo &);
> void func3(const Foo &);
>
> void f()
> {
>    func0(Foo());
>    func1(Foo());
>    func2(Foo());
>    func3(Foo());
> }
>
> Compiling with -O2 and "-fno-stack-protector -fno-exceptions" for
> clarity, on g++ 4.4.3, gives the following:
>
> 00000000 <f()>:
>   0:   55                              push   %ebp
>   1:   89 e5                   mov    %esp,%ebp
>   3:   81 ec 18 04 00 00       sub    $0x418,%esp
>   9:   8d 85 f8 fb ff ff       lea    -0x408(%ebp),%eax
>   f:   89 04 24                mov    %eax,(%esp)
>  12:   e8 fc ff ff ff                  call   13 <_Z1fv+0x13>
>  17:   8d 85 f8 fc ff ff       lea    -0x308(%ebp),%eax
>  1d:   89 04 24                mov    %eax,(%esp)
>  20:   e8 fc ff ff ff                  call   21 <_Z1fv+0x21>
>  25:   8d 85 f8 fd ff ff       lea    -0x208(%ebp),%eax
>  2b:   89 04 24                mov    %eax,(%esp)
>  2e:   e8 fc ff ff ff                  call   2f <_Z1fv+0x2f>
>  33:   8d 85 f8 fe ff ff       lea    -0x108(%ebp),%eax
>  39:   89 04 24                mov    %eax,(%esp)
>  3c:   e8 fc ff ff ff                  call   3d <_Z1fv+0x3d>
>  41:   c9                              leave
>  42:   c3                              ret
>
> The function makes four function calls, each of which constructs a
> temporary for the parameter.  The compiler dutifully allocates stack
> space to construct these, but it seems to allocate separate stack
> space for each of the temporaries.  This seems unnecessary--since
> their lifetimes don't overlap, the same stack space could be used for
> each of them.  The real-life code I adapted this example from had a
> fairly large number of temporaries strewn throughout it, each of which
> were quite large, so this behavior caused the generated function to
> use up a pretty substantial amount of stack, for what seems like no
> good reason.
>
> My question is, is this expected behavior?  My understanding of the
> C++ standard is that each of those temporaries goes away at the
> semicolon, so it seems like they have non-overlapping lifetimes, but I
> know there are some exceptions to that rule.  Could someone comment on
> whether this is an actual bug, or required for some reason by the
> standard, or just behavior that not enough people have run into
> problems with?

It's a missed optimization and not easy to fix.

Richard.

> Thanks,
> Matt
>

Reply via email to