Допустим, есть простой тестовый код
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) {};
}
Который скомпилирован в CodeSourcery G++ (gcc 4.3.2) для «голого железа» ARM. Он также имеет очень стандартный скрипт компоновщика.
При компиляции в C (как main.c) объект «данные» попадает во Flash, как и ожидалось. При компиляции на C++ (как main.cpp) этот объект помещается в ОЗУ, и добавляется дополнительный код, который не делает ничего, кроме копирования значения из Flash в ОЗУ (значение уже вычислено, просто скопируйте!). Таким образом, компилятор может вычислить адрес, но почему-то не хочет «просто использовать его». Корень проблемы в умножении адреса - без умножения на "*2" обе версии работают как положено - "данные" помещаются во Flash. Также - когда "данные" объявлены как:
const int data = (int)(REGISTER)*2;
тоже все нормально.
Все файлы для компиляции C и C++ идентичны, разница только в вызове компилятора - g++ для main.cpp, gcc для main.c (с разницей в уровне предупреждений, а в c++ отключены RTTI и исключения).
Есть ли простой и элегантный способ преодолеть эту «проблему C++»? Мне нужны такие операции для создания константных массивов адресов битов в битовой области Cortex-M3. Это ошибка или, может быть, это какое-то странное ограничение компилятора C++?
Я знаю, что могу создавать объекты данных в файлах "C" и просто "extern" включать их в C++, но это не очень элегантно [;
Спасибо за помощь!