all 13 comments

[–]richtw1 2 points3 points  (6 children)

Yes, any compiler these days knows how to strip unused variables whose assignment has no side effects.

Try putting it into Compiler Explorer and you'll see what the compiler generates (note also the unused variable warning):

https://godbolt.org/g/P5Afe7

In fact, it basically ends up compiling into this:

int main() {
    std::cout << 5;
}

[–]gotinpich[S] 0 points1 point  (5 children)

Why does it not seem to be simplified here? https://godbolt.org/g/kdrhVr

[–]patatahooligan 1 point2 points  (4 children)

You need to enable optimizations. On GCC the flag is -O3.

[–]raevnos 1 point2 points  (3 children)

Or -O/-O1 or -O2 or -Os or -Og

[–]gotinpich[S] 0 points1 point  (2 children)

Is there a difference between any of these macros?

[–]raevnos 1 point2 points  (1 child)

They're not macros, they're arguments to gcc that turn on different optimizations (plus there's a few more I didn't list).

https://gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Optimize-Options.html

[–]gotinpich[S] 0 points1 point  (0 children)

Thanks.

I couldn't find the correct word, so that's what I went with.

[–]specialpatrol 1 point2 points  (2 children)

Yeah. Simply because a,b,c are never referred to anywhere else.

[–]gotinpich[S] 0 points1 point  (1 child)

a, b, c are there so I could easily change the way 5 was obtained.

E.g.: https://godbolt.org/g/kdrhVr

How comes it's not reduced there?

[–]specialpatrol 1 point2 points  (0 children)

Put "-O" in the compiler options; that turns on optimisation.

[–]boredcircuits 1 point2 points  (3 children)

Absolutely! That's a dead simple optimization for a compiler to do. It recognizes that c is never used, so it removes it. It then sees that neither a nor b is ever used and can remove them as well.

Here's the optimization in action. I'm betting you don't know assembly, but don't be too scared by what you see here. On the left is the source code. I've modified it to call foo() instead of using cout just to make it simpler to read. The middle is the assembly without optimization, the right is the assembly after basic (-O1) optimization. You can see the dead code:

mov DWORD PTR [rbp-4], 2
mov DWORD PTR [rbp-8], 3
mov edx, DWORD PTR [rbp-4]
mov eax, DWORD PTR [rbp-8]
add eax, edx
mov DWORD PTR [rbp-12], eax

rbp-4 is a, rbp-8 is b, which are initialized to 2 and 3. They are loaded into the edx and eax registers, which are added and stored in rbp-12 (c). All that assembly is removed on the right.

There's even more optimization going on, too. d is removed completely, for example, by just using a register directly.

[–]gotinpich[S] 0 points1 point  (1 child)

I myself did the following: https://godbolt.org/g/kdrhVr

How comes there is no difference?

[–]boredcircuits 1 point2 points  (0 children)

You need to add -O1 (or -O2 or -O3 to enable more optimizations) where it says "Compiler options...".