Can a constexpr function call a function that returns void?

This is what I would like to do:

void g() { std::cout << "smth1" << std::endl; std::cout << "smth2" << std::endl; } constexpr bool f() {return g(), true;} 

The compiler ( gcc version 4.8.2) is unhappy with this, since g not constexpr . Is there a way around this?

0
source share
2 answers

The point of constexpr is that it can be fully expanded at compile time. It is not possible for the compiler to put side effects at runtime (using cout ) into what is actually a more complex compile time constant. In other words: at run time, no function call will be made for constexpr functions!

Fortunately, the solution is easy!

Change f to constexpr bool f() { return true;}

and your condition:

 g(); if(f()) { // ... } 
+3
source

Any evaluation of a function called in evaluating a constant expression should not have any side effects. In C ++ 11, the rules are actually much stricter, allowing only one return as the function body, but not relevant to this issue.

The compiler does not have the right to remove code from the constexpr function in order to execute it. You are not required to write such code in the first place.

However, it is normal to have code with side effects inside the constexpr function if the control flow never passes through it during a static evaluation.

This is valid C ++ 11.

 void g() { std::cout << "hello, world" << std::endl; } constexpr bool f(const bool p = false) { return p ? (g(), false) : true; } 

And you can call f as follows.

 constexpr auto x = f(); // ok 

Since p is false at compile time, the compiler does not need to evaluate the call to g . At run time, you can call f with any argument, as if it were not a constexpr function.

 f(false); // ok f(true); // ok, produces output at run-time 

What you cannot do is evaluate it in constant expression with the parameter set to true .

 constexpr auto x = f(true); // compile-time error 

Of course, this example is contrived beyond any limitations, and you just have to write

 constexpr bool f() noexcept { return true; } 

or use a variable

 constexpr auto toggle = true; 

if that's all you need.

0
source

All Articles