I need to have volatile member function in my class (which is trivial and has standard layout), so that class instances can be declared volatile (needed for memory-mapped register access).
However, I found that GCC is not willing to call static constexpr functions from volatile members. clang is just fine with that.
Here is the simplified code example: https://gcc.godbolt.org/z/36rE7h
#include <cstddef>
#include <cstdint>
class B {
public:
static constexpr uint32_t genMask()
{
return 0xFF;
}
uint32_t get(size_t word) const volatile
{
constexpr uint32_t mask = genMask();
return data[word] & mask;
}
private:
uint32_t data[5];
};
uint32_t fun()
{
constexpr uint32_t my_mmio_reg_addr = 0x8000BEEF;
volatile B *b = new (reinterpret_cast<uint32_t *>(my_mmio_reg_addr)) B;
return b->get(0);
}
GCC complains with
In member function 'uint32_t B::get(size_t) const volatile':
13:43: error: 'this' is not a constant expression
13 | constexpr uint32_t mask = genMask();
| ^
If I change
constexpr uint32_t mask = genMask();
with
constexpr volatile uint32_t mask = genMask();
GCC compiles code just fine, but then it treats mask as volatile, always re-reading it's value resulting in non-optimal code.
Why volatile member specifier affects local constexpr variables and static constexpr member functions? Is it a bug in GCC or some dark side of C++ spec?
Why *this is somehow involved here, if it's only local variables and static member function involved?