Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Purpose of constexpr

This is more of a philosophical question rather than practical code snippet, but perhaps C++ gurus can enlighten me (and apologies if it's been asked already).

I have been reading Item 15 in Meyers's "Effective Modern C++" book, as well as this thread: implicit constexpr? (plus a reasonable amount of googling). The item goes over usage of constexpr for expressions, namely that it defines functions that can return compile time values given compile time inputs. Moreover, the StackOverflow thread I referred to shows that some compilers are perfectly capable of figuring out for themselves which function invocation results are known at compile time.

Hence the question: why was constexpr added to the standard as compared to defining when compilers should derive and allow static/compile-time values?

I realise it makes various compile-only (e.g. std::array<T, constexpr>) definitions less predictable, but on the other hand, as per Meyers's book, constexpr is a part of the interface,..., if you remove it, you may cause arbitrarily large amounts of client code to stop compiling. So, not only having explicit constexpr requires people to remember adding it, it also adds permanent semantics to the interface.

Clarification: This question is not about why constexpr should be used. I appreciate that having an ability to programatically derive compile-time values is very useful, and employed it myself on a number of occasions. It's a question on why it is mandatory in situations where compiler may deduce const-time behaviour on its own.

Clarification no. 2: Here is a code snippet showing that compilers do not deduce that automatically, I've used g++ in this case.

#include <array>

size_t test()
  {
  return 42;
  }

int main()
  {
  auto i = test();
  std::array<int, i> arrayTst;
  arrayTst[1] = 20;
  return arrayTst[1];
  }

std::array declaration fails to compile because I have not defined test() as constexpr, which is of course as per standard. If the standard were different, nothing would have prevented gcc from figuring out independently that test() always returns a constant expression.

This question does not ask "what the standard defines", but rather "why the standard is the way it is"?

like image 724
RomanK Avatar asked Mar 02 '15 23:03

RomanK


People also ask

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.

Which is better const or constexpr?

The principal difference between const and constexpr is the time when their initialization values are known (evaluated). While the values of const variables can be evaluated at both compile time and runtime, constexpr are always evaluated at compile time.

Where is constexpr defined?

constexpr stands for constant expression and is used to specify that a variable or function can be used in a constant expression, an expression that can be evaluated at compile time. The key point of constexpr is that it can be executed at compile time.

When to use #define vs constexpr?

#define (also called a 'macro') is simply a text substitution that happens during preprocessor phase, before the actual compiler. And it is obviously not typed. constexpr on the other hand, happens during actual parsing. And it is indeed typed.


1 Answers

Before constexpr the compilers could sometimes figure out a compile time constant and use it. However, the programmer could never know when this would happen.

Afterwards, the programmer is immediately informed if an expression is not a compile time constant and he or she realizes the need to fix it.

like image 110
Zan Lynx Avatar answered Oct 04 '22 15:10

Zan Lynx