c++ - 使用方法失败更改 constexpr 对象成员

标签 c++ object gcc c++14 constexpr

我试图通过一种方法更改 constexpr 对象成员的值,但我不明白为什么它在这种特定情况下不起作用:

#include <iostream>

struct test
{
    int m_counter = 0;

    constexpr test()
    {
        m_counter++;
        m_counter++;
        increment();
        increment();
        increment();
    }

    constexpr void increment()
    {
        m_counter++;   
    }

    constexpr int value() const
    {
        return m_counter;
    }
};

template<int value>
constexpr void check()
{
    std::cout << value << std::endl;
}

// constexpr test t; // value = 3, why ?

int main()
{
    constexpr test t; // value = 5, ok
    check<t.value()>();
}

我不明白为什么在全局范围内创建对象时值是 3。 msvc 和 clang 在这两种情况下都显示 5 但不是 gcc。谁错了?

最佳答案

这似乎是一个 g++ 错误,可从 g++ 5.1 到 g++ 7.0 重现。我认为这是一个错误,因为这种行为看起来很荒谬。我尝试了这个代码片段,我相信如果变量是全局变量,编译器只会执行第一个 increment() 调用,而忽略其他调用:

constexpr test()
{
    m_counter++; // executed
    m_counter++; // executed
    increment(); // executed
    increment(); // NOT executed
    increment(); // NOT executed
}

// [...] will print 3

constexpr test()
{
    m_counter++; // executed
    m_counter++; // executed
    increment(); // executed
}

// [...] will print 3

constexpr test()
{
    m_counter++; // executed
    m_counter++; // executed
}

// [...] will print 2

constexpr test()
{
    m_counter++; // executed
    m_counter++; // executed
    increment(); // executed
    increment(); // NOT executed
    increment(); // NOT executed
    increment(); // NOT executed
    increment(); // NOT executed
    increment(); // NOT executed
}

// [...] will print 3

基本上,构造函数中只会执行一个increment()。添加更多 increment() 调用没有任何效果。但是,添加更多的 m_counter++ 指令将正常工作。

constexpr test()
{
    m_counter++; // executed 
    m_counter++; // executed
    increment(); // executed
    increment(); // NOT executed
    m_counter++; // executed
    m_counter++; // executed
    increment(); // NOT executed
    increment(); // NOT executed
}

// [...] will print 5

我在 g++ 错误跟踪器上将其报告为错误 #80039 .

关于c++ - 使用方法失败更改 constexpr 对象成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42783428/

相关文章:

c++ - 使用 string erase() 和 string length() 从字符串中删除某些字符

javascript - 读取对象内部的对象为未定义

c++ - 在 C++ 中为游戏创建对象

javascript - 如何在 JavaScript 中动态访问对象的属性?

c - 不带 "return"命令返回

python - OpenCV-contrib/Python/Windows:Tracker.write()在matrix_wrap.cpp中引发错误,Tracker.read()使Python崩溃

c++ - 如何在 C++ 中对三元组进行排序?

c++ - 是否需要清理堆栈内容?

c - 如何强制 Eclipse CDT MinGW 工具链使用 mingw32-g++.exe?

gcc - 如果编译器搜索路径中存在真实 ld 可执行文件,如何强制 GCC 使用 ld.gold?