使用constexpr函数在g ++中的不同行为 - 7.0 /访问硬件

时间:2016-11-18 18:46:10

标签: c++ constexpr reinterpret-cast

我使用以下代码访问某些MCU寄存器。

#include <stdint.h>

struct MCU {
    struct Timer {
        volatile uint8_t r1;
        template<int N> struct Address;
    };
};
template<>
struct MCU::Timer::Address<0> {
    static constexpr uint8_t value = 0x25;
};

template<typename Component, int Number>
constexpr Component* getBaseAddr() {
    return reinterpret_cast<Component*>(Component::template Address<Number>::value);
}

struct Test {
    static void foo() {
        p->r1 = 42;    
    }
    static constexpr auto p = getBaseAddr<MCU::Timer, 0>();
};

int main() {
    Test::foo();

    while(true) {}
}

在avr-g ++ 6.2.1中,这很好用。但现在使用avr-g ++ 7.0我得到错误:

in constexpr expansion of 'getBaseAddr<MCU::Timer, 0>()'
bm10a.cc:23:58: error: value '37u' of type 'MCU::Timer*' is not a constant expression
     static constexpr auto p = getBaseAddr<MCU::Timer, 0>();

我得出的结论是,版本6.2.1并不存在混淆,7.0版本就是! reinterpret_cast导致非constexpr表达式。

那么,有没有解决方案将寄存器地址声明为constexpr?

1 个答案:

答案 0 :(得分:0)

根据phil1970的可能解决方案是使用getBaseAddr()作为内联函数或其别名:

struct Test {
    static void foo() {
        p()->r1 = 42;    
    }
    static constexpr auto p = getBaseAddr<MCU::Timer, 0>;
};