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.
constexprfunctions andconstexprconstructors are implicitlyinline" Which then implies that you need a definition in every translation unit (source file) where the function is used, and you can have multiple definitions in different source files provided that they're equivalent (see ODR).