Во встроенном мире люди на протяжении веков писали аппаратные (-конфигурации) -регистрации-сопоставления как структуры, очень простой пример для 32-разрядного оборудования:
#define hw_baseaddr ((uintptr_t) 0x10000000)
struct regs {
uint32_t reg1;
uint32_t reg2;
};
#define hw_reg ((volatile struct regs *) hw_baseaddr)
void f(void)
{
hw_reg->reg1 = 0xdeadcafe;
hw_reg->reg2 = 0xc0fefe;
}
Это очень хорошо работает, компилятор (gcc, по крайней мере, на нашей платформе) признает, что hw_reg
ссылается на один и тот же адрес (который известен и постоянный во время компиляции) и ld
имеет его только один раз, Второй st
(store) выполняется с 4-байтным смещением с одной инструкцией - снова на нашей платформе.
Как воспроизвести это поведение с помощью современного С++ (post С++ 11) без использования #defines
?
Мы пробовали много вещей: static const
внутри и снаружи классов и constexpr
. Они оба не любят (неявные) reinterprest_cast<>
.
Отвечая на комментарий о том, зачем его менять: я боюсь, что это в основном слава и слава. Но не только. С этой отладкой кода C может быть сложно. Представьте, что вы хотите регистрировать все обращения к записи, этот подход потребует, чтобы вы переписывали все повсюду. Однако здесь я не ищу решение, которое упростит конкретную ситуацию, я ищу вдохновение.
РЕДАКТИРОВАТЬ. Чтобы уточнить некоторые комментарии: я задаю этот вопрос, чтобы не менять какой-либо код, который работает (и был написан в 1990-х годах). Я ищу решение для будущих проектов, потому что я не совсем доволен реализацией define
и спрашивал себя, обладает ли современный С++ превосходной возможностью.