【问题标题】:Are there any caveats in C++ with constexpr / static function usage in volatile members?在 volatile 成员中使用 constexpr / static 函数的 C++ 中是否有任何警告?
【发布时间】: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


【解决方案1】:

原来是已知的GCC bughttps://gcc.gnu.org/bugzilla/show_bug.cgi?id=80456

根据我的测试,问题首次出现在 GCC 4.9 中,自 GCC 10.2 起未修复。

不幸的是,在后备箱中也没有修复它。

【讨论】:

    猜你喜欢
    • 2018-01-08
    • 1970-01-01
    • 2016-10-05
    • 2014-12-07
    • 2021-05-17
    • 1970-01-01
    • 2020-03-10
    • 2020-09-20
    • 2017-01-12
    相关资源
    最近更新 更多