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

ads*_*s00 6 c++ gcc object constexpr c++14

我试图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()>();
}
Run Code Online (Sandbox Code Playgroud)

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

Vit*_*meo 5

这似乎是一个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
Run Code Online (Sandbox Code Playgroud)

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

// [...] will print 3
Run Code Online (Sandbox Code Playgroud)

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

// [...] will print 2
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

基本上,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
Run Code Online (Sandbox Code Playgroud)

我在g ++ bug跟踪器上报告了这个,就像bug #80039一样.