Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it still better to prefer pre-increment over post-increment?

It used to be the case that pre-increment would be preferred because an overloaded post-increment on a class necessitated the return of a temporary copy that represented the state of the object before the increment.

It seems this is no longer a serious concern (so long as inlining is in place), since my old C++ compiler (GCC 4.4.7) seems to optimize the following two functions down into identical code:

class Int {
    //...
public:
    Int (int x = 0);
    Int & operator ++ ();
    Int operator ++ (int) {
        Int x(*this);
        ++*this;
        return x;
    }
};

Int & test_pre (Int &a) {
    ++a;
    return a;
}

Int & test_post (Int &a) {
    a++;
    return a;
}

The resulting assembly for both functions is:

    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    pushq   %rbx
    .cfi_def_cfa_offset 16
    .cfi_offset 3, -16
    movq    %rdi, %rbx
    call    _ZN3IntppEv
    movq    %rbx, %rax
    popq    %rbx
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc

If nothing is inlined, however, there seems to still be a benefit to preferring pre-increment to post-increment, since test_post is forced to call out into operator++(int).

Let's assume operator++(int) is inlined as an idiomatic copy constructor, call to the pre-increment, and return of the copy, as illustrated above. If the copy constructor is inlined or the default copy constructor implementation, is that sufficient information for the compiler to optimize post-increment so that test_pre and test_post become identical functions? If not, what other information is required?

like image 955
jxh Avatar asked May 04 '15 17:05

jxh


3 Answers

Besides being potentially more efficient, the main reason why you should (usually) prefer pre-increment over post-increment is that the former is what you really meant in the first place.

When you write a loop header like

for ( std::size_t i = 0; i < numElements; i++ )

you don't mean "pls add one to the value of i and then give me its old value". You don't care about the return value of the expression i++ at all! So why make the compiler jump through hoops and give the one return value that takes the most work to get?

I realize the compiler will usually optimize the unnecessary extra work away anyway, but why not just say what you mean instead of hoping for the compiler to figure out what you mean?

like image 66
antred Avatar answered Oct 03 '22 16:10

antred


Typically the post-increment operator in user defined types involved creating a copy which is slower and more expensive than the typical pre-increment operator.

Therefore the pre-increment operator should be used in preference for user-defined types.

Also it is good style to be consistent and therefore pre-increment should also be preferred with built in types.

Example:

struct test
{
    // faster pre-increment
    test& operator++() // pre-increment
    {
        // update internal state
        return *this; // return this
    }

    // slower post-increment
    test operator++(int)
    {
        test c = (*this); // make a copy
        ++(*this); // pre-increment this object
        return c; // return the un-incremented copy
    }
};

The compiler can not be expected to optimise post-increment for user defined types as their implementation is a convention, not something the compiler can deduce.

like image 28
Galik Avatar answered Oct 03 '22 15:10

Galik


Yes. It shouldn't matter for built-in types. For such types, the compiler can easily analyze the semantics and optimize them — if that doesn't change the behavior.

However, for class-type, it may (if not does) matter, because the semantic could be more complex in this case.

class X { /* code */ };

X x;

++x;
x++; 

The last two calls could be entirely different and may perform different things, just like these calls:

x.decrement(); //may be same as ++x (cheating is legal in C++ world!)
x.increment(); //may be same as x++

So dont let yourself trapped for the syntactic sugar.

like image 44
Nawaz Avatar answered Oct 03 '22 14:10

Nawaz