[Bug c++/71113] New: Adding "const" to value in constexpr constructor places const object in .bss instead of .rodata
freddie_chopin at op dot pl
gcc-bugzilla@gcc.gnu.org
Sat May 14 10:15:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71113
Bug ID: 71113
Summary: Adding "const" to value in constexpr constructor
places const object in .bss instead of .rodata
Product: gcc
Version: 6.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: freddie_chopin at op dot pl
Target Milestone: ---
Take a look at following test case:
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --
class X
{
public:
constexpr X(void* pointer) :
pointer_{pointer}
{
}
private:
void* pointer_;
};
#define PERIPHERAL1 (void*)0x20000000
const X xxx {PERIPHERAL1};
int main()
{
}
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --
Execute test:
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --
$ g++ test.cpp && objdump -x --syms --demangle a.out | grep xxx
0000000000400608 l O .rodata 0000000000000008 xxx
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --
Everything's fine. Now just add one trivial change, which does _NOT_ change any
logic (at least in my opinion (; ). Replace:
constexpr X(void* pointer) :
with
constexpr X(void* const pointer) :
And the object is placed in .bss, not in .rodata...
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --
$ g++ test.cpp && objdump -x --syms --demangle a.out | grep xxx
0000000000600a58 l O .bss 0000000000000008 xxx
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --
There's no problem if an address of "real" object is used, so for example
something like this works fine in both cases:
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --
int something;
const X xxx {&something};
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --
The use case may seem a bit strange, but the macro definition like the one used
in the example is used commonly in hardware headers for microcontrollers. They
usually look like this:
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --
#define PERIPH_BASE ((uint32_t)0x40000000U)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000U)
#define USART1_BASE (APB2PERIPH_BASE + 0x1000U)
#define USART1 ((USART_TypeDef *) USART1_BASE)
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 --
(USART_TypeDef is a typedef of an anonymous struct with layout of peripheral
registers)
The behaviour was noticed in GCC compiled for "arm-none-eabi-", version 5.3.1,
but the same thing happens in a desktop version 6.1.1 on Arch Linux.
More information about the Gcc-bugs
mailing list