【发布时间】:2020-09-23 01:27:29
【问题描述】:
我需要在我的类中具有 volatile 成员函数(这很简单并且具有标准布局),以便可以将类实例声明为 volatile(访问内存映射寄存器所需的)。
但是,我发现 GCC 不愿意从 volatile 成员中调用静态 constexpr 函数。 clang 就好了。
这是简化的代码示例: 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 抱怨
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();
| ^
如果我改变了
constexpr uint32_t mask = genMask();
与
constexpr volatile uint32_t mask = genMask();
GCC 可以很好地编译代码,但它会将 mask 视为 volatile,总是重新读取它的值,从而导致代码非最优。
为什么 volatile 成员说明符会影响本地 constexpr 变量和静态 constexpr 成员函数?它是 GCC 中的错误还是 C++ 规范的某些阴暗面?
为什么*this会以某种方式在这里涉及,如果它只涉及局部变量和静态成员函数?
【问题讨论】:
-
我怀疑是编译器错误。我不认为
volatile成员函数很常见。 -
我确信这是一个 gcc 编译器错误。如果你添加一个间接层并在外部函数中调用静态
B::genMask(),GCC 会编译它:godbolt.org/z/xhc4sP。我认为 GCC 错误地认为genMask()是一个 non-static 成员函数。 -
@Justin,感谢您增加信心,我也怀疑它是一个错误,只是想仔细检查一下我的假设是否正确然后会转到 GCC bugzilla
标签: c++ compiler-errors static-methods constexpr volatile