Declaring constexpr functions or methods - c++

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?

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.

Related

confusion about constexpr function body

cppreference said the following about the body of a constexpr function:
the function body must not contain:
a definition of a variable of non-literal type
a definition of a variable of static or thread storage duration.
All I understood about a constexpr function is that the statements in its body should be evaluated at compile-time so that the call expression can be evaluated at compile-time. Am I true?
Since C++14, the standard allows the body to contain variable definitions of literal types. So what about those definitions, are they evaluated at compile-time or runtime? since non-constexpr variables are allowed also.
What I think I misunderstood is that the compiler shall be able to evaluate at compile-time every statement in a constexpr function body. Does this true since C++14?
To make my confusion clear, I have this simple example:
// assuming std::is_literal_type<T> is true.
constexpr T f() { T t{}; return t; };
I can't understand how the compile behaves with the above snippet. Variable t is an automatic non-const variable and gets defined at run-time not compile-time; so it basically cannot appear in a constexpr declaration. Does this means, the compiler will never evaluate f() at compile-time because it has a statement, that's T t;, which will be evaluated at runtime only.
My confusion is increased when I have tried:
constexpr T result = f();
and it compiles successfully!. Does this mean f() are evaluated at compile-time? if yes, what about the runtime definition of t?
My second question is about why static-duration variables are not allowed in the body of a constexpr function.
the statements in its body should be evaluated at compile-time
...along at least one possible code path.
Or, as the cpprefenrce page you're quoting puts it,
there exists at least one set of argument values such that an invocation of the function could be an evaluated subexpression of a core constant expression
The function can be doing disk I/O if it wants to, as long as there is an if branch that skips it.
Variable t is ... defined at run-time not compile-time
It's defined in both. There is a run-time definition of the function (actual machine code compiled and written to the object file) and also there is a compile-time version of the function, a bunch of AST nodes or some sort of internal compiler representation of them. In a constexpr context, compile-time version will be evaluated and replaced by its result. In runtime context, a function call instruction will be compiled.

Constexpr constructor fails to satisfy the requirements, but still constexpr. Why?

The standard says about template constexpr functions/constructors in dcl.constexpr/6:
If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression. If no specialization of the template would satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the template is ill-formed, no diagnostic required.
The interesting part is:
fail to satisfy the requirements for a ... constexpr constructor, that specialization is still a ... constexpr constructor
So, even if a constructor is marked with constexpr, it may not be used in a constant expression.
Why does this rule exist? Why isn't constexpr removed, when a function doesn't satisfy the requirements?
The current behavior is bad in two ways:
the non-constexpr-ness isn't caught at the closest possible location, but at the actual constexpr expression, where it is used. So we have to find the offending part, where constexpr silently removed.
an object, which is intended to be statically initialized (because it has a constexpr constructor), will be dynamically initialized without any errors/warnings (because the constructor isn't "really" constexpr).
Does this rule have some pros, which balances the cons of it?
This rule allows you to write a templated constructor/function and mark it as constexpr even when it's not always constexpr (only at least sometimes).
For example, std::pair has constexpr constructors, but it is of course usable outside of constant expressions.
This is quite sensible, because otherwise you would have to duplicate all these functions (once with constexpr and once without), even if the code is exactly the same. Let's not even consider ambiguity.
Since it is generally impossible to prove that a template cannot ever satisfy constexpr, no diagnostic is required for it (but it's ill-formed so compilers can complain to you if they can prove this for a given case).
You are correct that this is not very useful if you want to specify "this function shall only be usable in constant expression", but that's not what this wording is aiming for.
Edit: To clarify, constexpr for functions only means "legal to evaluate inside a constant expression" (more precise wording here), not "can only be evaluated at compile-time". By contrast, constexpr variables must be initialized with a constant expression.
Another edit: We have exact wording to discuss, thanks to #JackAidley!
If the instantiated template specialization of a constexpr function template would fail to satisfy the requirements for a constexpr function,
the constexpr specifier is ignored and the specialization is not a constexpr function.
The problem with this is that "there is at least one set of arguments for which the function can be constant-evaluated" is part of the "requirements for a constexpr function". Therefore, compilers cannot implement this clause, since it is not possible to prove (in general) whether such a set exists for a given function (or a function template instantiation). You either have to muddy this requirement further or give up on this aspect. It seems the committee chose the latter.
In earlier versions of the suggestion for the change to the language, it operated as you suggest:
If the instantiated template specialization of a constexpr function
template would fail to satisfy the requirements for a constexpr
function,the constexprspecifier is ignored and the specialization is
not a constexpr function.
But it was later changed. I was unable to track down any definitive answer to your question but I think that it is reasonable to believe that the answer is that constexpr make other semantic changes to the code and these are retained even though the function is no longer usable in other constexpr statements. If you look at defect report 1358 which includes the change to the current wording, you can see an intermediate form of words that includes the a note about retaining const status regardless.
I also think that while the retention of constexpr status is unintuitive, both of your arguments against it are wrong:
Catching the constexpr when the template instantiation is made goes against how C++ templates usually work - you only get an error when you try and use the template in a way it cannot be used for that type; merely not being able to complete the entire signature is not an error. To introduce special case mechanics for constexpr would be unnecessarily confusing and limit usefulness since you'd now need to write different templates for constexprable and un-constexprable types.
Because it maintains the constexpr specifier the fallback isn't to general runtime dynamic initialisation but to dynamic initialisation at the time at which statics are initialised. Which may cause problems because of the Static Initialisation Order Fiasco but does at least happen before the main() function is entered.

Static data member with initializer

Assuming one is never odr-used, is there a benefit of declaring a static const or static constexpr data member with an initializer over declaring and then defining one later? Is there a benefit to not needing a definition?
First, note that you can't define a static const data member where you declare it. The declaration doesn't become a definition no matter what you do (such as providing an initializer). However, a static constexpr data member doesn’t need a definition, and the static const data member of integral type with initializer doesn’t need a definition if it’s never ODR-used.
ODR: the One Definition Rule, in the C++11 standard §3.2 [basic.def.odr].
Providing a definition is non-trivial in a header file – for a non-template class the direct approach would lead fast to violations of the ODR, with the linker complaining. Thus a benefit of not defining is that it makes it easy to use header-only modules. And a benefit of defining is that it makes it easy to use any type whatsoever, and supports ODR-use.
There are already a host of SO questions dealing with practical solutions to the requirement of definition for ODR use, with respect to header-only modules.
The ODR has a special exemption for templates for this, and that’s the basis of one practical solution. Just provide the definition in a class template, and use a dummy argument to instantiate the template. Another practical solution is to place the definition in a function, essentially a Meyers’ singleton.

Example of non odr-used variable defined in the program [duplicate]

This just came up in the context of another question.
Apparently member functions in class templates are only instantiated if they are ODR-used.
Could somebody explain what exactly that means. The wikipedia article on One Definition Rule (ODR) doesn't mention "ODR-use".
However the standard defines it as
A variable whose name appears as a potentially-evaluated expression
is odr-used unless it is an object that satisfies the requirements for
appearing in a constant expression (5.19) and the lvalue-to-rvalue
conversion (4.1) is immediately applied.
in [basic.def.odr].
Edit: Apparently this is the wrong part and the entire paragraph contains multiple definitions for different things. This might be the relevant one for class template member function:
A non-overloaded function whose name appears as a
potentially-evaluated expression or a member of a set of candidate
functions, if selected by overload resolution when referred to from a
potentially-evaluated expression, is odr-used, unless it is a pure
virtual function and its name is not explicitly qualified.
I do however not understand, how this rule works across multiple compilation units? Are all member functions instantiated if I explicitly instantiate a class template?
It's just an arbitrary definition, used by the standard to
specify when you must provide a definition for an entity (as
opposed to just a declaration). The standard doesn't say just
"used", because this can be interpreted diversely depending on
context. And some ODR-use doesn't really correspond to what one
would normally associate with "use"; for example, a virtual
function is always ODR-used unless it is pure, even if it isn't
actually called anywhere in the program.
The full definition is in §3.2, second paragraph, although this
contains references to other sections to complete the
definition.
With regards to templates, ODR-used is only part of question;
the other part is instantiation. In particular, §14.7 covers
when a template is instantiated. But the two are related: while
the text in §14.7.1 (implicit instantiation) is fairly long, the
basic principle is that a template will only be instantiated if
it is used, and in this context, used means ODR-used. Thus,
a member function of a class template will only be instantiated
if it is called, or if it is virtual and the class itself is
instantiated. The standard itself counts on this in many
places: the std::list<>::sort uses < on the individual
elements, but you can instantiate a list over an element type
which doesn't support <, as long as you don't call sort on
it.
In plain word, odr-used means something(variable or function) is used in a context where the definition of it must be present.
e.g.,
struct F {
static const int g_x = 2;
};
int g_x_plus_1 = F::g_x + 1; // in this context, only the value of g_x is needed.
// so it's OK without the definition of g_x
vector<int> vi;
vi.push_back( F::g_x ); // Error, this is odr-used, push_back(const int & t) expect
// a const lvalue, so it's definition must be present
Note, the above push_back passed in MSVC 2013. This behavior is not standard compliant - both gcc 4.8.2 and clang 3.8.0 failed, with error message:
undefined reference to F::g_x

inline vs. constexpr?

With the new C++11 standard, when should I use the inline keyword over the constexpr keyword? Does the constexpr keyword offer any additional optimization over inline, or does it merely assert that things must be computed at compile-time?
Why does constexpr work on the GCC in some cases where the call is not constant, such as calling foo(x) on a non-constexpr variable? Is this a bug in the GCC or is it actually part of the standard?
Asserting that something can be computed at compile-time is a pretty strong kind of optimization.
Inlining merely removes a function call, by copy/pasting the function body into the call site. The function body still has to be executed, you just save the overhead of a function call.
But if you make the same code be evaluated at compile-time, it is free at runtime.
But neither inline nor constexpr are primarily about optimization. inline's main purpose is to suppress the one-definition-rule, so that functions can be defined in headers (which is useful for templates, and incidentally, also makes the inlining optimization easier)
And constexpr is there because it is useful in metaprogramming, and incidentally, it may help the compiler better optimize the code, by moving more computations to compile-time.
To quote wikipedia:
C++0x will introduce the keyword constexpr, which allows the user to
guarantee that a function or object constructor is a compile-time
constant.
Mark functions inline if they are super short. Mark functions as constexpr if the results are required at compile time. (Template parameters or array sizes). I believe a function can be both if needed.
A constant expression function or constructor can be called with
non-constexpr parameters. Just as a constexpr integer literal can be
assigned to a non-constexpr variable, so too can a constexpr function
be called with non-constexpr parameters, and the results stored in
non-constexpr variables. The keyword only allows for the possibility
of compile-time constancy when all members of an expression are
constexpr.
So, GCC is not incorrect in this.
While inline says to the compiler "This function is used somewhere in this translation unit and is not public to other object files", it is likely that the compiler inserts the body of the function into the caller. constexpr functions say to the compiler "This function has no side effects and does not depend on preconditions other than the parameter itsself."
constexpr variables just say "This variable does not change and its data can be included into the code.". However it makes a difference if you define a constexpr variable in a function static or nonstatic, eg. if a constexpr array is nonstatic, gcc just moves the data with hardcoded mov-instructions onto the stack, while static constexpr just stores the data in the .text-section.
Lambda expressions without capture assigned to a variable can be constexpr other than with capture, because without they need no memory to save the capture and they work like an empty class with overloaded operator() (but they can even be casted to plain function pointers with a simple unary plus: +[]{}).