Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why constexpr works for impure functions

while browsing one of my old questions on constexpr I stumbled onto a very(IMHO) important comment. Basically it boils down to : (this is legal C++11 :( )

 constexpr double f(bool b)
 {
 return b? 42:42/(rand()+1); // how pure is rand ;)
 }

My question is what is the reason this is allowed by the standard. Since Im a big fan of referential transparency I hope they have a good reason :) and I would like to know it.

BTW there is related Q but most of the A even dont mention pure thing, or when they do they dont specify the reasoning why std allows this. Relation between constexpr and pure functions

like image 573
NoSenseEtAl Avatar asked Nov 08 '12 18:11

NoSenseEtAl


1 Answers

In the standard, the relevant requirement is buried below the main list of requirements for constexpr functions. It's in §7.1.5/5:

For a constexpr function, if no function argument values exist such that the function invocation substitution would produce a constant expression (5.19), the program is ill-formed; no diagnostic required.

§5.19 defines the requirements for constant expressions, such that you can't call rand().

The relaxed restriction allows you to have functions that are conditionally pure. Your example f(true) is a valid template argument, but f(false) is not.

The downside, of course, is that the compiler won't verify that a constexpr function can actually be used for its intended purpose. You need to write test cases.

Ah, litb's answer is also correct. (But this one is worded more simply.)

like image 112
Potatoswatter Avatar answered Nov 15 '22 21:11

Potatoswatter