https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124438
Bug ID: 124438
Summary: A "static const" class member is sometimes more const
than a plain 'const'
Product: gcc
Version: 15.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: rdiez-2006 at rd10 dot de
Target Milestone: ---
Hi all:
I am using a self-built GCC arm-none-eabi cross-compiler version 15.2.
One day, I wasn't caffeinated enough and I wrote this invalid code
(simplified):
const int b = ( some_class_member == 0 )
? 0
: b;
GCC did not issue the expected "may be used uninitialized" warning and the
debug firmware (built without optimisation) did not run correctly. It took me a
while to slap my forehead.
I then tried to reproduce this lack of warning, but I haven't managed. Every
time I simplify the code to post an example, the warning comes up as expected.
Very frustrating.
However, in the course of my investigation, I came across an interesting
nuance. When compiling without optimisation, a "static const" member is
apparently more const than a plain "const" member.
This is the simplified test I came up with:
--------8<--------8<--------
class CTest
{
const bool m_my_bool_only_const = false;
static const bool m_my_bool_const_and_static = false;
public:
int test ( void )
{
if ( m_my_bool_only_const )
{
int a;
return a;
}
if ( m_my_bool_const_and_static )
{
int b;
return b;
}
return 0;
}
};
static CTest testInstance;
static volatile int testResult = testInstance.test();
int main ( void )
{
return 0;
}
--------8<--------8<--------
When I compile that program with "gcc -Wall test.cpp", a "may be used
uninitialized" [-Wmaybe-uninitialized] warning gets issued for 'a', but not for
'b'.
You can play with the code above here:
https://godbolt.org/z/fE31zar9E
This is not just about warnings: it is a lack of optimisation when not
optimising. I know it sounds weird, but let me explain.
I usually flash and debug non-optimised firmwares, and with assertions enabled.
If I enable optimisation, debugging gets difficult.
Even when NOT optimising with say "-O2", GCC will discard code it knows it will
be never executed. I have a lot of "if ( FEATURE_XXX_ENABLED )" in the sources,
and this kind of discarding helps keep the debug firmwares reasonably small.
The first benefit of this discarding is a faster flash time (many
microcontrollers write to their embedded flash memories rather slowly).
Besides, a full firmware with all options enabled would not fit in the flash
memory anyway.
That is why it would be nice if a plain "const" were the same as a "static
const". This does seem to happen everywhere, except for class members. In the
example above, code is generated for the first 'if' statement checking the
"plain const" class member, but it shouldn't be.
Or is there a reason why "static const" and "const" should be treated
differently in C++ class members for code-discarding purposes?
Thanks in advance,
rdiez