2016-11-18 4 views
5

いくつかのMCUレジスタにアクセスするには、次のコードを使用します。g ++のconstexpr関数での動作が異なります - ハードウェアへのアクセス/アクセラレータ

#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 confromingされていないと7.0です! reinterpret_castは非constexpr式につながります。

したがって、レジスタアドレスをconstexprとして宣言するソリューションはありますか? phil1970に従って

+0

これはC++ 11、C++ 14とCで私のためにビルド++ bog-standard 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

可能な解決策は、インライン関数、またはそのための別名としてgetBaseAddr()を使用することになる。

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