Why ** not ** declare a `constexpr` function?

Any function consisting only of a return statement can be declared constexpr and, thus, will be evaluated at compile time if all arguments are constexpr , and only constexpr functions constexpr called in their body. Is there a reason why not declare such a constexpr function?

Example:

  constexpr int sum(int x, int y) { return x + y; } constexpr i = 10; static_assert(sum(i, 13) == 23, "sum correct"); 

Can someone provide an example in which declaring a constexpr function would do some harm?




Some initial thoughts:

Even if there should be no good reason for declaring a function not constexpr I could assume that the constexpr keyword has a transitional role: its absence in code that does not require compilation time estimates will allow compilers that do not implement evaluation compilation time to compile this code ( but with a reliable rejection of the code that needs them, as is done using constexpr ).

But I do not understand: if there should not be good reason for ever declaring a function not constexpr , why not every function in the standard library is declared constexpr ? (You cannot argue that this has not been done yet, because there has not yet been enough time to do it, because doing it for everyone is not a problem - contrary to the solution for each individual function, if you make it constexpr or not). --- I know that N2976 intentionally does not require cstrs for many standard types of libraries, such as containers, as this would be too restrictive to the possible implementation. Let's exclude them from the argument and just ask ourselves: as soon as the type of the standard library has constexpr cstr, why did every function working on it declare constexpr ?

In most cases, you also cannot argue that you can not declare a constexpr function simply because you do not plan to use compilation time: because if other evtl. will use your code, they may see such use that you are not. (But provided, of course, for type types, type types, etc.)

So, I think there should be a good reason and a good example for intentional not declaring a constexpr function?

(with “every function” I always mean: every function that meets the requirements for constexpr , that is, defined as single return, takes only type arguments with constexpr cstrs and calls only constexpr functions.)

Question Why constexpr std::forward discard constexpr -ness? is a special case of this.

+49
c ++ c ++ 11 const function-declaration constexpr
Feb 25 2018-11-11T00: 00Z
source share
3 answers

Functions can only be declared constexpr , if they obey the rules for constexpr --- there are no dynamic constexpr , does not allocate memory, does not call functions not constexpr , etc.

Declaring a function in the standard library as constexpr requires ALL implementations to follow these rules.

Firstly, it requires checking for each function that it can be implemented as constexpr , which is a long job.

Secondly, this is a big limitation for implementations, and will prohibit many debugging implementations. Therefore, it is only worthwhile if the benefits outweigh the costs or the requirements are sufficiently stringent that the implementation to a large extent must obey the rules of constexpr in any case. Performing this assessment for each function is again a long job.

+28
Feb 25 '11 at 10:59
source share

I think what you call a partial rating . What you are concerned with is that some programs can be divided into two parts - the part that requires information about the execution time, and the part that can be executed without any information about the execution time, and that theoretically you can just fully appreciate part of a program that does not need any runtime information before you start running the program. There are some programming languages ​​that do this. For example, the D programming language contains an interpreter built into the compiler that allows code to be executed at compile time, provided that it meets certain restrictions.

There are several major problems when working with partial pricing. Firstly, this greatly complicates the compiler logic, because the compiler will have to be able to simulate all the operations that you could put into an executable program at compile time. This, in the worst case, requires that you have a full interpreter inside the compiler, which creates a complex problem (writing a good C ++ compiler) and makes it an order of magnitude more complicated.

I believe that the reason for the current constexpr specification is simply to limit the complexity of compilers. The cases that he limited are fairly easy to verify. There is no need to implement loops in the compiler (which can cause a number of problems, for example, what happens if you get an infinite loop inside the compiler). It also shuns the compiler, which might need to evaluate statements that can invoke segfaults at run time, for example, after a bad pointer.

Another consideration to keep in mind is that some functions have side effects, such as reading from cin or opening a network connection. Such functions, in principle, cannot be optimized at compile time, since this will require knowledge that is available only at run time.

To summarize, there is no theoretical reason why you could not partially evaluate C ++ programs at compile time. In fact, people do this all the time. For example, compiler optimizations are programs that try to do this as much as possible. Metaprogramming templates is one example where C ++ programmers try to execute code inside the compiler, and some wonderful things can be done with templates partially, because the rules for templates form a functional language that is easier for the compiler to execute. Moreover, if you are thinking about a compromise between the author’s clock and the programming clock, metaprogramming the templates shows that if you’re okay, the programmers lean back to get what they want, you can create a rather weak language (template system) and save the complexity of the language is simple. (I say “weak” as “not particularly expressive,” not “weak” in the sense of computability theory).

Hope this helps!

+11
Feb 25 '11 at 4:29
source share

If a function has side effects, you will not want to mark it with constexpr . Example

I cannot get any unexpected results, actually it looks like gcc 4.5.1 just ignores constexpr

+2
Feb 25 '11 at 5:15
source share



All Articles