constexpr int fun(int x, int y) { return x+y; }
fun(5,6) // << constant expression?
tl;dr
5 and 6 are constant expressions. Thus fun(5,6) also is a constant expression and will be evaluated at compile time where this is mandatory (non-type templates for instance).
stuff...
I had a quick look into the standard and I hope I didn't miss any important points.
We already know from @42's answer:
According to N4527 int is a valid paramter type for a constexpr function since it is a literal type (since it is a scalar type which is by §3.9/10 of the same document a literal type). Therefore, fun is a valid constexpr function.
It provides code that puts fun(5,6) into a context where a constant expression is required and it seems to be accepted by certain compilers.
Now the question is whether this is valid, standard-conformant behaviour.
§5.20 from N4527 says:
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:
- here comes a large list of things that prevent expressions from being core constant expression
That list does not contain "constexpr function with constant expression arguments" which are therefore core constant expressions (unless they are undefined when used).
Thus, if 5 and 6 are constant expressions, then fun(5,6) is a constant expression if fun is a valid constexpr function and is defined before using it. The given function satisfies the required constraints in §7.1.5/3 and is a valid constexpr function.
Both 5 and 6 are integer literals of type int as per §2.13.2
1) An integer literal is a sequence of digits that has no period or exponent part, with optional separating single quotes that are ignored when determining its value. [...]
2) The type of an integer literal is the first of the corresponding list in Table 5 in which its value can be represented.
Suffix: none, Decimal literal: int, long int, long long int
Now looking at §5.20 again we see: both are constant expressions.
function(x, y)with non-constxandymight also be evaluated at compile time if the optimizer realizes thatxandywill always have the same value. It just isn't required to do so, and the result cannot be used where aconstexpris required.