Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

constexpr exp, log, pow

I'd like to use constexpr versions of standard <cmath> functions like exp, log, pow in a portable way. I currently have a non-portable solution g++ treats these functions as constexpr - a non-compliant extension of C++, but I am concerned about portability and future-proofing (I imagine that this extension might one day be removed from g++).

I am interested in constexpr versions of these functions, not template metaprograms - I want the same functionality to be available both at compile time and runtime. I do not need C compatibility, but I do need fast implementations - naive implementations such as Taylor Series expansions would be too slow.

How can I implement such functionalities? I am specifically interested in exp, log, and pow

Some tangentially related things I've learned from my research

  • The standard-compliant versions of these functions aren't technically constexpr because they must have side-effects (e.g. setting errno) to maintain C compatibility
  • In C++11, an implementation was allowed to make these functions constexpr, but as of C++14, this is prohibited (per the first answer to this question and the answer to this question). This is part of the reason that I am concerned that the functions may not be constexpr in future versions of g++
  • g++'s implementation of each math function foo just calls a built-in function __builtin_foo, which is treated as constexpr. I could perhaps start calling the __builtin_foo functions rather than the foo functions - these might remain constexpr in future versions of g++ even if the corresponding foo functions are made compliant - but this only helps with future-proofing, not with portability.
like image 934
user1476176 Avatar asked May 22 '18 23:05

user1476176


People also ask

What does constexpr mean?

constexpr indicates that the value, or return value, is constant and, where possible, is computed at compile time. A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations.

Is constexpr always evaluated at compile time?

constexpr functions will be evaluated at compile time when all its arguments are constant expressions and the result is used in a constant expression as well.

Should constexpr be static?

So you should definitely use static constexpr in your example. However, there is one case where you wouldn't want to use static constexpr . Unless a constexpr declared object is either ODR-used or declared static , the compiler is free to not include it at all.

Why does constexpr need to be static?

A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.


2 Answers

Have you ever watch Sprout's implementaion?

Sprout is header-only library that provide C++11/14 constexpr based Containers, Algorithms, Random numbers, Parsing, Ray tracing, Synthesizer, and others.

https://github.com/bolero-MURAKAMI/Sprout/tree/master/sprout/math

like image 150
yumetodo Avatar answered Sep 28 '22 02:09

yumetodo


Check out gcem which provides compile time mathematical functions. They can be called just like the ones in std but using the gcem prefix.

like image 43
BullyWiiPlaza Avatar answered Sep 28 '22 04:09

BullyWiiPlaza