This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++0x rvalue references get clobbered somehow


(I sent a copy of this mail to gcc-help a few days ago but didn't
get a response.)

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

#include <cstdlib>
#include <iostream>

namespace awesome {

    namespace detail_region {
        template<typename T> struct Typedef { typedef T t; };
        template<typename T> T &&fw(typename Typedef<T>::t &&x) { return x; }

        template<typename ...> struct tuple;

        template<> struct tuple<> {
            template<typename T, typename ...Args> T *capply(void *place, Args &&...args) const {
                return new (place) T(fw<Args>(args) ...);

        template<typename Hd, typename ...Tl> struct tuple<Hd, Tl ...> {
            Hd &&head;
            tuple<Tl ...> tail;
            tuple(Hd &&h, Tl &&...t) : head(fw<Hd>(h)), tail(fw<Tl>(t) ...) {}

            template<typename T, typename ...Args> T *capply(void *place, Args &&...args) const {
                return tail.capply<T>(place, fw<Args>(args) ..., fw<Hd>(head));

    struct region {
            template<typename ...Args> struct spork {
                detail_region::tuple<Args ...> args;

                spork(Args &&...x) : args(detail_region::fw<Args>(x) ...) {}

                template<typename T> operator T *() const {
                    // ::operator new(1);
                    // std::cout << "hi\n";
                    std::rand();  // XXX any function call here seems to cause problems

                    static char raw_[sizeof (T)];
                    return args.template capply<T>(raw_);


            template<typename ...Args> spork<Args ...> alloc(Args &&...args) {
                return spork<Args ...>(detail_region::fw<Args>(args) ...);

using namespace std;

int main() {
    using awesome::region;

    region r;
    int *p = r.alloc(123);
    cout << *p << '\n';

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.

Can you explain to me what's going on here? How can I fix this
code? Or is this a bug in g++? (And is this the right place to ask?)

Thanks in advance

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]