Let's say there is a simple test code
typedef struct
{
int first;
int second;
int third;
} type_t;
#define ADDRESS 0x12345678
#define REGISTER ((type_t*)ADDRESS)
const int data = (int)(®ISTER->second)*2;
int main(void)
{
volatile int data_copy;
data_copy = data;
while(1) {};
}
Which is compiled in CodeSourcery G++ (gcc 4.3.2) for bare metal ARM. It also has a very standard linker script.
When compiled in C (as main.c) the object "data" goes into Flash, as expected. When compiled in C++ (as main.cpp) this object goes into RAM, and additional code is added which does nothing more than copy the value from Flash to RAM (the value is already calculated, just copy!). So the compiler can calculate the address, but somehow doesn't want to "just use it". The root of the problem is the multiplication of the address - without "*2" multiplication both versions work as expected - "data" is placed in Flash. Also - when "data" is declared as:
const int data = (int)(REGISTER)*2;
also everything is fine.
All files for C and C++ compilation are identical, the only difference is the call to compiler - g++ for main.cpp, gcc for main.c (with differences in the level of warnings, and c++ has RTTI and exceptions disabled).
Is there any easy and elegant way to overcome this "C++ problem"? I do require such operations for creating const arrays of addresses of bits in bitband region of Cortex-M3. Is this a bug, or maybe that is some strange limitation of the C++ compiler?
I know that I can create data objects in "C" files and just "extern"-include them in C++, but that's not very elegant [;
Thank you for all help!