I'm trying to change the value of a constexpr
object member via a method but i don't understand why it's not working in this specific case :
#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()>();
}
I don't understand why value is 3 when i create object in global scope. msvc and clang display 5 in both cases but not gcc. Who is wrong?
This seems to be a g++ bug, reproducible from g++ 5.1 up to g++ 7.0. I think it is a bug because the behavior seems nonsensical. I played around with the snippet and I believe that the compiler only executes the first increment()
call if the variable is global, disregarding the other invocations:
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
Basically, only one increment()
inside the constructor will be executed. Adding more increment()
calls has no effect. Adding more m_counter++
instructions will however work properly.
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
I reported this on the g++ bug tracker as as bug #80039.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With