I've been investigating the assembly output for a simple C++ loop involving a const array and const size, and I've encountered peculiar version-specific behavior with GCC on Compiler Explorer.
My original question focused on a seemingly redundant add eax, ecx instruction in optimized GCC assembly. When trying to reproduce this on Compiler Explorer with GCC 11.2, I encountered a linker error (even with a small array of 8 numbers), which was not present in GCC 15, MSVC, or ICX. When I later re-tested GCC 11.2 (and even the MSVC and ICX compilers), the linker error disappeared, and the assembly output also changed to be more optimized (similar to what GCC 15 or MSVC/ICX produce).
My C++ code:
#include <iostream>
#include <vector> // Changed to vector as per original question's context, though assembly difference is seen with array too
#include <iomanip>
int main() {
const int data_size = 8; // Small size for quick testing
// Using std::vector as in the original question, but the issue was seen with arrays too.
const std::vector<int> data = {0, 1, 2, 3, 4, 5, 6, 7};
int sum = 0;
for (int i = 0; i < data_size; ++i) {
sum += data[i];
}
std::cout << "Sum: " << sum << std::endl;
return 0;
}
Upon re-testing GCC 11.2, the linker error was gone. Furthermore, the generated assembly differed from my initial observation and now looked more optimized, aligning more with MSVC/ICX and GCC 15, but still not showing the peculiar add eax, ecx from the original question.
https://godbolt.org/z/M5nPhjhT9
(This link shows various compiler versions and flags. Observe the differences, especially between GCC 11.2 and GCC 15, and the behavior with/without -fno-pie flags.)
What could have caused the initial linker error with GCC 11.2 on Compiler Explorer for such a simple const array/vector initialization and loop? Was it an ODR violation that higher optimization levels or later compiler versions happened to bypass?