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

时间:2017-03-14 10:27:03

标签: 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。谁错了?

1 个答案:

答案 0 :(得分: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

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 ++错误跟踪器上报告了这个问题,如bug #80039