Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't abs constexpr?

Tags:

In <cinttypes>, since C++11, there are the following two overloads:

std::intmax_t abs( std::intmax_t n ); std::intmax_t imaxabs( std::intmax_t n ); 

Why aren't those two functions constexpr?

like image 863
Shoe Avatar asked Dec 30 '14 16:12

Shoe


People also ask

Is constexpr guaranteed?

Quick A: constexpr guarantees compile-time evaluation is possible if operating on a compile-time value, and that compile-time evaluation will happen if a compile-time result is needed.

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.

Does constexpr improve performance?

Understanding constexpr Specifier in C++ constexpr is a feature added in C++ 11. The main idea is a performance improvement of programs by doing computations at compile time rather than run time.


1 Answers

I can't give a good reason for why abs couldn't be constexpr and apparently neither can gcc. When I use gcc 4.9.2 with this program:

#include <cstdlib> #include <cinttypes> #include <cassert>  constexpr intmax_t abs3 = std::abs(3); constexpr intmax_t absneg3 = std::abs(-3); int main() {     assert(abs3 == absneg3); } 

it compiles and runs to completion with no warnings or errors. You can try it here. However, clang++ (version 3.5.0) throws a compile-time error:

abs.cpp:6:20: error: constexpr variable 'abs3' must be initialized by a constant expression.

I think that clang++ actually gets it right here, because in section 27.9.2 [c.files] of the 2011 standard, it says:

The contents of header are the same as the Standard C Library header , with the following changes:

— the header includes the header instead of , and

— if and only if the type intmax_t designates an extended integer type (3.9.1), the following function signatures are added:

intmax_t abs(intmax_t);

imaxdiv_t div(intmax_t, intmax_t);

which shall have the same semantics as the function signatures intmax_t imaxabs(intmax_t) and imaxdiv_t imaxdiv(intmax_t, intmax_t), respectively.

In the current working draft of the C++ standard, as in the published 2014 version, it says in section 17.6.5.6 [constexpr.functions]:

This standard explicitly requires that certain standard library functions are constexpr (7.1.5). An implementation shall not declare any standard library function signature as constexpr except for those where it is explicitly required.

So the result, for now, is that these functions are still not constexpr according to the standard (which you knew) but they could be, as demonstrated by the gcc compiler.

like image 117
Edward Avatar answered Sep 19 '22 17:09

Edward