On 2016-10-06 22:21, David Brown wrote:
>>
>> That's what I mean by GCC randomly enforcing constexpr restrictions.
>> Some cases still work, others are broken. This is explicitly forbidden
>> by the standard and GCC is moving towards more enforcement.
>
> Can you give an example of where this does not work? Exact code, and
> gcc version and target?
--------------------------------------------------------------
#include <stdint.h>
#define PORT (*(volatile uint32_t*)(0x42424242))
constexpr volatile uint32_t* test(volatile uint32_t& x) {
return &x;
}
constexpr volatile uint32_t* addr = test(PORT);
--------------------------------------------------------------
Works with 4.7 and 4.8, doesn't compile with GCC >= 4.9 on x64 and ARM.
While your example:
--------------------------------------------------------------
#define REGISTER (*(volatile uint32_t *)0x42424242)
constexpr uintptr_t register_addr = (uintptr_t) ®ISTER;
--------------------------------------------------------------
still compiles with GCC, it doesn't compile with Clang:
error: constexpr variable 'register_addr' must be initialized by a
constant expression
note: cast that performs the conversions of a reinterpret_cast is not
allowed in a constant expression
> As far as I can tell, this sort of code is perfectly legal - gcc does
> not get to "break" it, and it certainly should not be doing so
> "randomly".
C++14: 5.20 Constant expressions [expr.const]
<<<
A conditional-expression e is a core constant expression unless the
evaluation of e, following the rules of the abstract machine (1.9),
would evaluate one of the following expressions:
...
— (2.13) a reinterpret_cast
>>>