Wednesday, February 7, 2024

[SOLVED] What are differences in the different build types when it comes to optimization in the GCC complier for C++ (CLion)?

Issue

FYI: I am in CLion. This is just something I am curious about, but I made a program to use all my ram for fun. It created a int* array = new int[3'900'000'000]{};.

When I run this program in debug build option, it does use all of my ram. But in the release mode, it doesn't use up any of my ram. I even tried to modify certain values in the array to see if that would force the complier to create the full array. When in the release mode, I also tried to fill every single number in the array with something with the fill method and manually using a for loop.


Solution

int* array = new int[3'900'000'000]{};

was probably optimized out by the compiler because it realized that this memory isn't used, and the allocation isn't necessary.

This optimization is called heap elision. See also Is the compiler allowed to optimize out heap memory allocations?

In general, compilers will attempt to optimize your code in every conceivable way, as long as the observable behavior remains the same. They do this according to the as-if rule. See also What exactly is the "as-if" rule?

Use Compiler Explorer to gain an understanding of what optimizations are actually applied. For example, GCC with optimization enabled (-O2) optimizes

int main() {
    int* array = new int[3'900'000'000]{};
}

to

main:
        xor     eax, eax
        ret

It's as if the allocation never happened. A way to trick the compiler and disable optimizations is to use volatile:

int main() {
    volatile int* array = new int[3'900'000'000]{};
    delete array;
}

The compiler cannot optimize this out because volatile reads and writes are considered observable behavior. However, you might get std::bad_alloc because the allocation is too large.



Answered By - Jan Schultke
Answer Checked By - Clifford M. (WPSolving Volunteer)