2016-11-18 46 views
5

我使用下面的代碼來訪問一些MCU寄存器。g ++中的constexpr函數的不同行爲 - 7.0 /訪問硬件

#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-克++ 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不confroming和7.0! reinterpret_cast會導致非constexpr表達式。

那麼,有沒有解決方案宣佈一個註冊地址爲constexpr?

+0

此生成對我在C++ 11,C++ 14和C++採用bog標準GCC 6.2.0的1z模式。 [但GCC 7的C++ 17支持更徹底](https://gcc.gnu.org/projects/cxx-status.html#cxx1z)。你能澄清你正在嘗試使用哪種語言?然後我們可以追蹤這是否C++本身已經改變了。 –

+0

掛上...這段代碼裏面沒有43行...你在告訴豬肉嗎?請告訴我,我不僅浪費了我週五晚上20分鐘的時間! –

+0

另外GCC 7只是預發行版本,所以你使用的是_actual_版本?給出構建日期或'-v'輸出。 –

回答

0

根據phil1970一種可能的解決辦法是使用getBaseAddr()作爲內聯函數或別名爲:

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