2016-11-18 18 views
5

Tôi sử dụng mã sau để truy cập vào một số thanh ghi MCU.Hành vi khác nhau với hàm constexpr trong g ++ - 7.0/quyền truy cập vào phần cứng

#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) {} 
} 

Trong avr-g ++ 6.2.1 hoạt động tốt. Nhưng bây giờ với avr-g ++ 7,0 tôi nhận được lỗi:

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>(); 

Tôi đã đi đến kết luận, phiên bản 6.2.1 đó không phải là confroming và 7.0 là! reinterpret_cast dẫn đến các biểu thức không constexpr.

Vì vậy, có giải pháp nào để khai báo địa chỉ đăng ký dưới dạng constexpr không?

+0

này được xây dựng cho tôi trong C++ 11, C++ 14 và C++ Chế độ 1z với GCC 6.2.0. [Hỗ trợ C++ 17 của GCC 7 triệt để hơn, mặc dù] (https://gcc.gnu.org/projects/cxx-status.html#cxx1z). Bạn có thể làm rõ ngôn ngữ nào bạn đang cố gắng sử dụng không? Sau đó, chúng tôi có thể theo dõi xem liệu đây có phải là chính bản thân C++ đã thay đổi hay không. –

+0

Treo trên ... mã này không có 43 dòng trong đó ... bạn đang nói về heo? Xin vui lòng cho tôi biết tôi đã không chỉ lãng phí 20 phút của buổi tối thứ sáu của tôi! –

+0

Ngoài ra GCC 7 chỉ là bản phát hành trước khi phát hành, vì vậy phiên bản _actual_ bạn đang sử dụng là gì? Cung cấp ngày xây dựng hoặc đầu ra '-v'. –

Trả lời

0

Một giải pháp khả thi theo phil1970 sẽ được sử dụng getBaseAddr() là hàm inline hoặc một cái tên bí danh cho rằng:

struct Test { 
    static void foo() { 
     p()->r1 = 42;  
    } 
    static constexpr auto p = getBaseAddr<MCU::Timer, 0>; 
}; 
Các vấn đề liên quan