0

Consider the following simple code:

template<typename T>
struct Base {
    static constexpr int v = 0;
};

struct Derived : Base<int> {};

int main() {
    Derived d;
}

I compile it with GCC (8.3.0, 9.1.0, g++ -g -O0 test.cpp), then run GDB to examine the value of d:

(gdb) p d
$1 = {<Base<int>> = {static v = <optimized out>}, <No data fields>}

d.v is gone... I tried to use -ggdb, -ggdb3, -fvar-tracking with no success.

If I compile with clang (clang++ -g -O0 test.cpp), I see the expected result:

(gdb) p d
$1 = {<Base<int>> = {static v = 0}, <No data fields>}

This output is also seen with GCC if Base is not a template class:

(gdb) p d
$1 = {<Base> = {static v = 0}, <No data fields>}

Where did d.v go? Why was it optimized out? Is it possible to prevent this optimization without modifying the source code?

Evg
  • 25,259
  • 5
  • 41
  • 83
  • 3
    you never access the value, it is nowhere referenced. Why should it be part of any code? – Klaus Oct 30 '19 at 08:10
  • 1
    https://godbolt.org/z/lf3pkz here you can see that the whole program is simply a `return 0;`, so everything is optimized away. – mch Oct 30 '19 at 08:10
  • 1
    `constexpr` values are supposed to be compile-time constants, so unless you [ODR-use](https://en.cppreference.com/w/cpp/language/definition#ODR-use) them there's no need to keep it in the generated code. – Some programmer dude Oct 30 '19 at 08:12
  • @mch, this is also true for clang, but with clang I can still see the value of `d.v`. – Evg Oct 30 '19 at 08:16
  • @Klaus, because it is a non-optimized build with debug info in it. If `Base` is not a template, I can see the value of `d.v`, though it is never accessed and nowhere referenced. – Evg Oct 30 '19 at 08:20
  • 1
    @mch Are you sure it's nowhere in [here](https://godbolt.org/z/X8bPKi)? – Max Langhof Oct 30 '19 at 08:34
  • Does this answer your question? [gcc -O0 still optimizes out "unused" code. Is there a compile flag to change that?](https://stackoverflow.com/questions/39832958/gcc-o0-still-optimizes-out-unused-code-is-there-a-compile-flag-to-change-tha) – Klaus Oct 30 '19 at 08:53
  • @Klaus, I don't see how it answers my question. Both GCC and Clang optimize everything out, but Clang keeps some debug info that GCC doesn't. This question is not about code optimization, but about debug info in the compiled binary. I removed a misleading tag. – Evg Oct 30 '19 at 09:00
  • @Klaus, the fact that my simple program does nothing is absolutely irrelevant. This is just a minimal example. My real code does a lot of things, but some values (that are never accessed in the code) are still optimized out. The fact is that Clang keeps the info I want, and GCC doesn't, but only for class templates. Microsoft compiler also keeps that information. So, the 'efforts' argument is not very compelling. What is useless in an optimized build, is not always useless in a debug one, even if it is not accessed directly in the code. – Evg Oct 30 '19 at 09:45

1 Answers1

0

Even though it doesn't have to respect it, by using constexpr and providing an initialized value, you're strongly hinting to the compiler that it should constant-fold Base::v.

Gcc has a -fkeep-static-consts flag that might do what you want.

parktomatomi
  • 3,851
  • 1
  • 14
  • 18
  • Tried to compile with `-O0 -g -fkeep-static-consts`, and I'm still getting ``. – Evg Oct 30 '19 at 08:23
  • I was able to reproduce what you had, but I didn't have any luck getting it to allocate for 0. The dumb bit is that if I initialize a top-level global int to zero? Doesn't optimize it out. It's something about being in that struct that makes it impossible to not optimize – parktomatomi Oct 30 '19 at 09:33