public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* C++0x rvalue refs get clobbered somehow
@ 2008-03-15  2:28 Lukas Mai
  0 siblings, 0 replies; only message in thread
From: Lukas Mai @ 2008-03-15  2:28 UTC (permalink / raw)
  To: gcc-help

Hello!

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.

Here's (a simplified version of) my code. Details like destructors,
dynamic memory management, etc are gone; it's just generic object
construction.

------------------------------------------------------------------
#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 {
        private:
            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_);
                }
            };

        public:

            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.
This is obviously a bug, either in my code or in g++.

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? (And is this the right place to ask?)

Thanks in advance
Lukas

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-03-15  2:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-15  2:28 C++0x rvalue refs get clobbered somehow Lukas Mai

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).