Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 528
user4713075 Avatar asked Mar 25 '15 16:03

user4713075


People also ask

How do I know if a function is constexpr?

The easiest way to check whether a function (e.g., foo ) is constexpr is to assign its return value to a constexpr as below: constexpr auto i = foo(); if the returned value is not constexpr compilation will fail.

Is not usable as a constexpr function because?

It means that compiler can't guarantee that your if-constexpr is always compile-time, hence the error about it. If you place all your arguments as template auto parameters of your function then it should compile well.

What is constexpr in C ++ 11?

The keyword constexpr was introduced in C++11 and improved in C++14. It means constant expression. Like const , it can be applied to variables: A compiler error is raised when any code attempts to modify the value. Unlike const , constexpr can also be applied to functions and class constructors.

Can a function return constexpr?

A constexpr function is a function that can be invoked within a constant expression. A constexpr function must satisfy the following conditions: It is not virtual. Its return type is a literal type.


2 Answers

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.

like image 187
user4713075 Avatar answered Oct 24 '22 11:10

user4713075


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.

like image 21
Columbo Avatar answered Oct 24 '22 12:10

Columbo