Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about optimization in C++

I've read that the C++ standard allows optimization to a point where it can actually hinder with expected functionality. When I say this, I'm talking about return value optimization, where you might actually have some logic in the copy constructor, yet the compiler optimizes the call out.

I find this to be somewhat bad, as in someone who doesn't know this might spend quite some time fixing a bug resulting from this.

What I want to know is whether there are any other situations where over-optimization from the compiler can change functionality.

For example, something like:

int x = 1;
x = 1;
x = 1;
x = 1;

might be optimized to a single x=1;

Suppose I have:

class A;

A a = b;
a = b;
a = b;

Could this possibly also be optimized? Probably not the best example, but I hope you know what I mean...

like image 457
Luchian Grigore Avatar asked Sep 22 '11 15:09

Luchian Grigore


3 Answers

Eliding copy operations is the only case where a compiler is allowed to optimize to the point where side effects visibly change. Do not rely on copy constructors being called, the compiler might optimize away those calls.

For everything else, the "as-if" rule applies: The compiler might optimize as it pleases, as long as the visible side effects are the same as if the compiler had not optimized at all.

("Visible side effects" include, for example, stuff written to the console or the file system, but not runtime and CPU fan speed.)

like image 135
sbi Avatar answered Sep 20 '22 21:09

sbi


It might be optimized, yes. But you still have some control over the process, for example, suppose code:

int x = 1;
x = 1;
x = 1;
x = 1;
volatile int y = 1;
y = 1;
y = 1;
y = 1;

Provided that neither x, nor y are used below this fragment, VS 2010 generates code:

    int x = 1;
    x = 1;
    x = 1;
    x = 1;
    volatile int y = 1;
010B1004  xor         eax,eax  
010B1006  inc         eax  
010B1007  mov         dword ptr [y],eax  
    y = 1;
010B100A  mov         dword ptr [y],eax  
    y = 1;
010B100D  mov         dword ptr [y],eax  
    y = 1;
010B1010  mov         dword ptr [y],eax  

That is, optimization strips all lines with "x", and leaves all four lines with "y". This is how volatile works, but the point is that you still have control over what compiler does for you.

Whether it is a class, or primitive type - all depends on compiler, how sophisticated it's optimization caps are.

Another code fragment for study:

class A
{
private:
    int c;

public:
    A(int b)
    {
        *this = b;
    }
    A& operator = (int b)
    {
        c = b;
        return *this;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    int b = 0;
    A a = b;
    a = b;
    a = b;
    return 0;
}

Visual Studio 2010 optimization strips all the code to nothing, in release build with "full optimization" _tmain does just nothing and immediately returns zero.

like image 23
Roman R. Avatar answered Sep 20 '22 21:09

Roman R.


This will depend on how class A is implemented, whether the compiler can see the implementation and whether it is smart enough. For example, if operator=() in class A has some side effects such optimizing out would change the program behavior and is not possible.

like image 29
sharptooth Avatar answered Sep 22 '22 21:09

sharptooth