Nan Xiao
Nan Xiao

Reputation: 17477

How to understand constexpr function has "everything it needs" to compute its result at compile-time?

I come across Demystifying constexpr, and am a little confused about the examples in this post.

According to the post, constexpr function definition is like this:

A constexpr function is able to compute its result at compilation time, if its input is known at compilation time.

In other words, any function that has "everything it needs" to compute its result at compile-time, can be a constant expression.

For add function:

int add(int a, int b)  
{
    return a + b;
}

Although the function is constexpr, you can use it with runtime value just the same:

int main(int argc, char argv)  
{
    return add(argc, argc);
}

But for another function:

int add_vectors_size(const std::vector<int> & a, const std::vector<int> & b)  
{
  return a.size() + b.size()
}

The explanation of it can't be used as "constexpr" is:

The compile time input are two vectors. Can we know at compile time the size of a vector? The answer is no. Thus, add_vectors_size cannot be a constant expression. We don't have "everything we need".

But per my understanding, for the first case, the argc value also can't be known during compile-time, and its value should be got at running time, correct? So how to understand constexpr function has "everything it needs" to compute its result at compile-time?

Upvotes: 2

Views: 692

Answers (3)

R Sahu
R Sahu

Reputation: 206607

The key requirement for a function to be a constexpr function:

If its input is known at compile time, its results can be computed at compile time.

However, a constexpr is also a regular function. If its inputs are known only at run time, its results will be computed at run time.

Given your example, if you use:

 constexpr int a = add(5, 10);

the result of the function call can be evaluated at compile time since its inputs are known at compile time.

Use of

return add(argc, argc);

is a valid use of the function too. The inputs to the function in this call are known only at run time. Hence, the result function call can be evaluated only at run time.

Upvotes: 2

Joseph D.
Joseph D.

Reputation: 12174

So how to understand constexpr function has "everything it needs" to compute its result at compile-time?

This line in the link refers to [1]:

constexpr int add(int a, int b)  
{
    return a + b;
}

static constexpr int val = add(3, 4); // [1] here

add() has two parameters which are literals.

The values are known at compile time which are 3 and 4.

But per my understanding, for the first case, the argc value also can't be known during compile-time, and its value should be got at running time, correct?

A variable or argument whose value can't be known during compile time can still be used as a parameter to a constexpr function. As long as the parameter type is a literal type.

Upvotes: 0

Nicol Bolas
Nicol Bolas

Reputation: 473447

But per my understanding, for the first case, the argc value also can't be known during compile-time

You're confusing "parameters" with "arguments".

Parameters are the things in the function declaration that represent stuff the user passes in. Arguments are the actual stuff the user passes in at the site of a particular function call.

argc is an argument. The value of this may or may not be a constant expression, and if it is not, a constexpr function is fine.

int is used as the type for a parameter to add. int is a type which can be a constant expression. Now, not every int value is a constant expression, but it is a type that could theoretically be one.

Therefore, add can be a constexpr function, because its parameter list uses types which can be constant expressions. This is about the nature of the function itself.

The type vector<T> can never be a constant expression (in C++17, at any rate). As such, no constexpr function can take one as a parameter. Nor can it use one internally.

Upvotes: 4

Related Questions