user4713075
user4713075

Reputation: 261

constexpr void function rejected

I have this very simple function which won't compile.

constexpr void func()
{
}

The error I'm getting is:

error: invalid return type 'void' of constexpr function 'constexpr void func()'

     constexpr void func()

In C++14, void is a literal type [§3.9/10]:

A type is a literal type if it is:

  • void; or
  • a scalar type; or
  • a reference type; or
  • an array of literal type; or
  • a class type (Clause 9) that has all of the following properties:
    • it has a trivial destructor,
    • it is an aggregate type (8.5.1) or has at least one constexpr constructor or constructor template that is not a copy or move constructor, and
    • all of its non-static data members and base classes are of non-volatile literal types.

Can someone explain why this is invalid?

Upvotes: 16

Views: 9396

Answers (3)

static_cats
static_cats

Reputation: 300

Taken from The C++ Programmig Language (4th Edition):

A constexpr function may not have side-effects.

So, what would be the purpose of a constexpr void function?

If you are aiming to do something like that:

constexpr void Twice(int &a)
{
    a *= 2;
}

You should consider changing to:

constexpr int Twice(int a)
{
    return 2 * a;
}

Upvotes: 0

Columbo
Columbo

Reputation: 60969

It is valid indeed, but not yet supported in GCC. An example in the standard actually includes constexpr functions returning void - see [dcl.constexpr]/1:

constexpr void square(int &x); // OK: declaration
 // [..]
constexpr void square(int &x) { // OK: definition
    x *= x;
}

Example on Coliru using Clang, which is conforming here.

Upvotes: 7

user4713075
user4713075

Reputation: 261

The proposal which made void a literal type was n3652 Relaxing constraints on constexpr functions. G++ decided to push this feature to version 5 (I was using 4.9.2):

G++ now supports C++14 extended constexpr.

constexpr int f (int i)
{
  int j = 0;
  for (; i > 0; --i)
    ++j;
  return j;
}

constexpr int i = f(42); // i is 42

Clang has had this implemented since version 3.4.

Upvotes: 10

Related Questions