Hello, On Wed, Mar 19, 2008 at 4:23 AM, Lukas Mai <[EMAIL PROTECTED]> 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