Is compiler allowed to call an immediate (consteval) function during runtime?

前端 未结 2 376
礼貌的吻别
礼貌的吻别 2021-01-02 17:02

This might be a stupid question, but I am confused. I had a feeling that an immediate (consteval) function has to be executed during compile time and w

2条回答
  •  自闭症患者
    2021-01-02 18:04

    To be more precise, I'd like to hear which of the following statements of the cited article are correct:

    1. An immediate function is only seen at compile time (and cannot be evaluated at run time)
    2. Symbols are not emitted for an immediate function
    3. Tools such as debuggers will not be able to show an immediate function

    Almost none of these are answers which the C++ standard can give. The standard doesn't define "symbols" or what tools can show. Almost all of these are dealer's choice as far as the standard is concerned.

    Indeed, even the question of "compile time" vs. "run time" is something the standard doesn't deal with. The only question that concerns the standard is whether something is a constant expression. Invoking a constexpr function may produce a constant expression, depending on its parameters. Invoking a consteval function in a way which does not produce a constant expression is il-formed.

    The one thing the standard does define is what gets "seen". Though it's not really about "compile time". There are a number of statements in C++20 that forbid most functions from dealing in pointers/references to immediate functions. For example, C++20 states in [expr.prim.id]/3:

    An id-expression that denotes an immediate function shall appear only

    • as a subexpression of an immediate invocation, or

    • in an immediate function context.

    So if you're not in an immediate function, or you're not using the name of an immediate function to call another immediate function (passing a pointer/reference to the function), then you cannot name an immediate function. And you can't get a pointer/reference to a function without naming it.

    This and other statements in the spec (like pointers to immediate function not being valid results of constant expressions) essentially make it impossible for a pointer/reference to an immediate function to leak outside of constant expressions.

    So statements about the visibility of immediate functions are correct, to some degree. Symbols can be emitted for immediate functions, but you cannot use immediate functions in a way that would prevent an implementation from discarding said symbols.

    And that's basically the thing with consteval. It doesn't use standard language to enforce what must happen. It uses standard language to make it impossible to use the function in a way that will prevent these things from happening. So it's more reasonable to say:

    1. You cannot use an immediate function in a way that would prevent the compiler from executing it at compile time.

    2. You cannot use an immediate function in a way that would prevent the compiler from discarding symbols for it.

    3. You cannot use an immediate function in a way that would force debuggers to be able to see them.

    Quality of implementation is expected to take things from there.

    It should also be noted that debugging builds are for... debugging. It would be entirely reasonable for advanced compiler tools to be able to debug code that generates constant expressions. So a debugger which could see immediate functions execute is an entirely desirable technology. This becomes moreso as compile-time code grows more complex.

提交回复
热议问题