0

What does the C++11 iso standard say about such an expression :

class MyClass
{
    public:
        constexpr int test()
        {
            return _x;
        }

    protected:
        int _x;
};

_x is a non-const used in a constexpr : will it produce an error, or will the constexpr be simply ignored (as when we pass a non-const parameter) ?

Vincent
  • 57,703
  • 61
  • 205
  • 388

2 Answers2

5

It's perfectly fine, though somewhat useless:

constexpr int n = MyClass().test();

Since MyClass is an aggregate, value-initializing it like that will value-initialize all members, so this is just zero. But with some polish this can be made truly useful:

class MyClass
{
public:
    constexpr MyClass() : _x(5) { }
    constexpr int test() { return _x; }
// ...
};

constexpr int n = MyClass().test();  // 5
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • "*The problem is of course that this is undefined behaviour, because the variable is uninitialized.*" No it isn't – you're value-initializing an instance of `MyClass`, so `MyClass::_x` is guaranteed to be 0. `MyClass m; constexpr int n = m.test();` would be UB. – ildjarn Sep 26 '12 at 18:53
  • @ildjarn: you're right, I forgot that there's no user-defined constructor. – Kerrek SB Sep 26 '12 at 20:47
1

If the expression does not resolve to a constant expression, then it cannot be used as such. But it can still be used:

#include <array>
constexpr int add(int a, int b)
{
  return a+b;
}
int main()
{
  std::array<int, add(5,6)> a1; // OK
  int i=1, 
  int j=10;
  int k = add(i,j); // OK
  std::array<int, add(i,j)> a2; // Error!
}
juanchopanza
  • 223,364
  • 34
  • 402
  • 480