Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compiler optimization

So I have a question for you. :) Can you tell me the output the following code should produce?

#include <iostream>
struct Optimized
{
    Optimized() { std::cout << "ctor" << std::endl; }
    ~Optimized() { std::cout << "dtor" << std::endl; }
    Optimized(const Optimized& copy) { std::cout << "copy ctor" << std::endl; }
    Optimized(Optimized&& move) { std::cout << "move ctor" << std::endl; }
    const Optimized& operator=(const Optimized& rhs) { std::cout << "assignment operator" << std::endl; return *this; }
    Optimized& operator=(Optimized&& lhs) { std::cout << "move assignment operator" << std::endl; return *this; }
};

Optimized TestFunction()
{
    Optimized a;
    Optimized b = a;
    return b;
}

int main(int argc, char* argv[])
{
    Optimized test = TestFunction();
    return 0;
}

My first response would be:

  1. ctor
  2. copy ctor
  3. move ctor
  4. dtor
  5. dtor
  6. dtor

and it IS true, but only if compiler optimization is turned off. When optimization is turned ON then the output is entirely different. With optimization turned on, the output is:

  1. ctor
  2. copy ctor
  3. dtor
  4. dtor

With compiler optimization, the test variable is the return variable.

My question is, what conditions would cause this to not be optimized this way?

I have always been taught that returning a struct/class which results in extra copy constructors could better be optimized by being passed in as a reference but the compiler is doing that for me. So is return a structure still considered bad form?

like image 717
BabelFish Avatar asked Aug 31 '11 17:08

BabelFish


People also ask

What does compiler optimization do?

In computing, an optimizing compiler is a compiler that tries to minimize or maximize some attributes of an executable computer program. Common requirements are to minimize a program's execution time, memory footprint, storage size, and power consumption (the last three being popular for portable computers).

What is optimizing in compiler design?

Code optimization is a program modification strategy that endeavours to enhance the intermediate code, so a program utilises the least potential memory, minimises its CPU time and offers high speed.

How does the C++ compiler optimize?

The C/C++ compiler compiles each source file separately and produces the corresponding object file. This means the compiler can only apply optimizations on a single source file rather than on the whole program. However, some important optimizations can be performed only by looking at the whole program.

Why do compilers use optimization code?

The code optimization in the synthesis phase is a program transformation technique, which tries to improve the intermediate code by making it consume fewer resources (i.e. CPU, Memory) so that faster-running machine code will result.


1 Answers

This is known as Copy Elision and is a special handling instead of copying/moving.

The optimization is specifically allowed by the Standard, as long as it would be possible to copy/move (ie, the method is declared and accessible).

The implementation in a compiler is generally referred to, in this case, as Return Value Optimization. There are two variations:

  • RVO: when you return a temporary (return "aa" + someString;)
  • NRVO: N for Named, when you return an object that has a name

Both are implemented by major compilers, but the latter may kick in only at higher optimization levels as it is more difficult to detect.

Therefore, to answer your question about returning structs: I would recommend it. Consider:

// Bad
Foo foo;
bar(foo);

-- foo can be modified here


// Good
Foo const foo = bar();

The latter is not only clearer, it also allows const enforcement!

like image 53
Matthieu M. Avatar answered Oct 11 '22 12:10

Matthieu M.