This is the mail archive of the gcc-bugs@gcc.gnu.org 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]

[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064

--- Comment #1 from Thiago Macieira <thiago at kde dot org> 2013-04-25 00:45:00 UTC ---
Here's why I'm asking:

QString has members like:

    QString arg(int, [other parameters]) const;

Which are used like so:

    return QString("%1 %2 %3 %4").arg(42).arg(47).arg(-42).arg(-47);
    // returns "42 47 -42 -47"

Right now, each call creates a new temporary, which is required to do memory
allocation. I'd like to avoid the new temporaries by simply reusing the
existing ones:

    QString arg(int, [...]) const &; // returns a new copy
    QString &&arg(int, [...]) &&; // modifies this object, return *this;

When these two overloads are present, every other call will be to rvalue-ref
and the others to lvalue-ref. That is, the first call (right after the
constructor) calls arg()&&, which returns an rvalue-ref. The next call will be
to arg()&, which returns a temporary, making the third call to arg()&& again.

I can get the desired behaviour by using the overloads:

    QString arg(int, [...]) const &; // returns a new copy
    QString arg(int, [...]) &&; // returns a moved temporary via return
std::move(*this);

However, the side-effect of that is that we still have 4 temporaries too many,
albeit empty (moved-out) ones. You can see this by counting the number of calls
to the destructor:

$ ~/gcc4.8/bin/g++ -fverbose-asm -fno-exceptions -fPIE -std=c++11 -S -o -
-I$QTOBJDIR/include /tmp/test.cpp | grep -B1 call.*QStringD
        movq    %rax, %rdi      # tmp82,
        call    _ZN7QStringD1Ev@PLT     #
--
        movq    %rax, %rdi      # tmp83,
        call    _ZN7QStringD1Ev@PLT     #
--
        movq    %rax, %rdi      # tmp84,
        call    _ZN7QStringD1Ev@PLT     #
--
        movq    %rax, %rdi      # tmp85,
        call    _ZN7QStringD1Ev@PLT     #


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