Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring constexpr functions or methods

I was wondering if there was any restrictions on where constexpr functions and methods have to be declared, like there are for inline functions and methods.

I know that inline functions or methods must be written in header files, to give the compiler access to their definition where they are called. It would make sense if there was something similar for constexpr, but I can't manage to find anything on that point...

So basically my questions are:

  • Can I write the definitions of constexpr functions in a header file without taking the risk of having a duplicate symbol?

  • Can I separate the declaration and definition of constexpr functions or methods?

like image 830
Eternal Avatar asked Jun 10 '14 23:06

Eternal


1 Answers

The place you define a constexpr function affects how you can use it. In particular:

C++14[expr.const]p2:

A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:

  • an invocation of an undefined constexpr function or an undefined constexpr constructor;

So you can't use a constexpr function in a constant expression (template argument, constexpr variable initializer, global variable initializer that needs to be evaluated statically, array bound expression, maybe others) if it's only been declared but not defined yet.

Similarly, as dyp commented,

C++14[dcl.constexpr]p2

constexpr functions and constexpr constructors are implicitly inline (7.1.2).

That implies the answer to your first question: defining the constexpr function in a header won't cause duplicate symbols. It also means that if you declare a constexpr function in a header, and then call it in a translation unit, even only at runtime, "An inline function shall be defined in every translation unit in which it is odr-used." from C++14[basic.def.odr]p4.

Note that the rules for constant expressions and calls in general are different: calls in general require the definition to be somewhere in the translation unit: constant expressions require the definition to be before the constant expression.

like image 88
Jeffrey Yasskin Avatar answered Oct 17 '22 01:10

Jeffrey Yasskin