This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: C++0x rvalue references get clobbered somehow
- From: "Doug Gregor" <doug dot gregor at gmail dot com>
- To: "Lukas Mai" <l dot mai at web dot de>
- Cc: gcc at gcc dot gnu dot org
- Date: Wed, 19 Mar 2008 09:24:01 -0400
- Subject: Re: C++0x rvalue references get clobbered somehow
- References: <200803190923.45770.l.mai@web.de>
Hello,
On Wed, Mar 19, 2008 at 4:23 AM, Lukas Mai <l.mai@web.de> wrote:
> I'm having problems with g++-4.3.0 and C++0x. Disclaimer: I don't
> understand rvalue references, but since I need (indirect) argument
> forwarding, I copied and modified an example from the web.
> (I believe detail_region::fw is equivalent to std::forward.)
>
> Here's (a simplified version of) my code. Details like destructors,
> dynamic memory management, etc are gone; it's just generic object
> construction.
[snip code]
>
> This code works fine (and prints 123) when compiled with
> g++ -std=c++0x -O2 (or -Os or -O). However, without optimization
> it produces output like -1207981096. This number changes if
> different function calls are used at the location marked XXX.
>
> Somehow args.head loses its value between construction (in alloc)
> and use (in capply), but only if optimizations are not enabled.
>
> I think args.head should be bound to the temporary value 123,
> which should stay alive until the next statement. But something
> seems to overwrite it before p is initialized.
I think you've tripped across a bug in the C++0x standard. GCC is
implementing exactly what the C++0x standard currently says, but
that's not what we want rvalue references to do :)
The issue, I believe, is that when forwarding built-in types like
integers, the compiler will end up making extra temporaries... and
tuple<int>::head will end up being bound to a temporary that doesn't
live long enough for your code to work (at -O0). This issue is being
tracked as GCC bug 34022, here:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34022
But the important part is that it is core issue 664 for C++0x, tracked here:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#664
Current status: the Core Working Group of the C++ committee agrees
that there is a problem, and what the general solution is, but we
don't yet have the wording to update the C++ standard (and, then, GCC)
to fix the problem. Note that, if I tweak your example to use the
following test case, it works (because we don't make more temporaries
of class type; just of built-in types):
struct X {
X(int value ) : value(value) {}
int value;
};
int main() {
using awesome::region;
region r;
X *p = r.alloc(X(123));
cout << p->value << '\n';
}
- Doug