'Guarantees on the Object lifetime of inline static Meyers singleton, with explicit placement in a section?
I have inherited some code that compiles fine under g++ 9 and 10, but gives a runtime error for both compilers when optimization is turned on (that is, compiling -O0 works, but compiling -Og gives a runtime error from the MMU.)
The problem is that there is a Meyers singleton defined in an inline static method of a class, and that object seems to be optimized away. There is a complication that the static object in the method is declared with a section attribute (this is the g++ language extension for placing options in specific sections in the object file.)
Here is a summary of the situation.
File c.hpp
namespace my_prod {
class C {
// C has a default c'tor
public:
static C& instance() {
static C c __attribute__((section("MY_C_SECTION")));
return c;
}
void f();
};
}
File c.cpp
#include "c.hpp"
using namespace my_prod;
void C::f() {
// implementation of f, doesn't use instance()
}
File p.hpp
namespace my_prod {
class P {
public:
static void g();
};
}
Then file p.cpp
#include "p.hpp"
#include "c.hpp"
using namespace my_prod;
void P::g() {
C::instance().f();
}
The linker script includes:
MEMORY
{
BIG_CHUNK (rw) : ORIGIN = <address>, LENGTH = <enormous>
}
SECTIONS
{
.my_space (NOLOAD) :
{
. = ALIGN(32);
*(MY_C_SECTION)
} > BIG_CHUNK
}
For both optimization levels, objdump -C -r -t p.o gives
00000000 w O MY_C_SECTION 00002220 my_prod::C::instance::c
(ie, so not local, not global, but it is weak.)
But objdump on the elf file shows that symbol in BIG_CHUNK when optimization is -O0, but missing when it is -Og.
It may be relevant that the project defines the following switches::
-ffunction-sections
-fdata-sections
-Wl,--gc-sections
although these switches are applied consistently for all builds.
The solution was to move the definition of the my_prod::C::instance() method into c.cpp. The symbol is then locally defined and not weak anymore, and appears in the final elf irrespective of the optimization level.
My question is, what are the rules of C++ that explain this behavior?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
