Is it possible to prevent static const members optimization using compiler command-line options?
Here is an example:
template <unsigned v1>
struct TRAITS {
static const unsigned val1 = v1;
};
template < class TRAITS >
struct foo {
static const unsigned x1 = TRAITS::val1;
};
int main () {
foo<TRAITS<1>> f1;
// SET BREAKPOINT HERE
return 0;
}
Compile:
g++ -g -O0 optimize_out.cpp
GDB:
gdb a.out
(gdb) break optimize_out.cpp:13
(gdb) r
(gdb) p f1
$1 = {static x1 = <optimized out>}
What is specific about this code is that classes are templates. Probably there is something in C++ standard that forces compiler to optimize fields away, even with -O0 ? When I don't use templates, values are not optimized away:
struct foo {
static const unsigned x1 = 1;
};
In this case I can see x1 in debugger
The short answer is that const makes no difference to optimization; it's to help catch bugs at compile-time.
“static const” is basically a combination of static(a storage specifier) and const(a type qualifier). The static determines the lifetime and visibility/accessibility of the variable.
Compiler specific pragma gcc provides pragma GCC as a way to control temporarily the compiler behavior. By using pragma GCC optimize("O0") , the optimization level can be set to zero, which means absolutely no optimize for gcc.
The short answer: A const is a promise that you will not try to modify the value once set. A static variable means that the object's lifetime is the entire execution of the program and it's value is initialized only once before the program startup.
You can use the used
attribute to tell the compiler to emit the definition even if it isn't needed by anything:
template <unsigned v1>
struct TRAITS {
static const unsigned val1 [[gnu::used]] = v1;
};
template < class TRAITS >
struct foo {
static const unsigned x1 [[gnu::used]] = TRAITS::val1;
};
Alternatively, you could add out-of-line definitions of the static variables (which would be needed anyway if you odr-used them) and add the attribute to those definitions:
template < class TRAITS >
const unsigned foo<TRAITS>::x1 [[gnu::used]];
template <unsigned v1>
const unsigned TRAITS<v1>::val1 [[gnu::used]];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With