gpt4 book ai didi

c++ - 编译器是否允许在运行时调用立即(consteval)函数?

转载 作者:行者123 更新时间:2023-12-02 02:02:13 27 4
gpt4 key购买 nike

这可能是一个愚蠢的问题,但我很困惑。我有一种感觉,立即(consteval)函数必须在编译时执行,而我们根本无法在二进制文件中看到它的主体。

This article明显支持我的感觉:

This has the implication that the [immediate] function is only seen at compile time. Symbols are not emitted for the function, you cannot take the address of such a function, and tools such as debuggers will not be able to show them. In this matter, immediate functions are similar to macros.

类似的强烈主张可能会在 Herb Sutter's publication 中找到。 :

Note that draft C++20 already contains part of the first round of reflection-related work to land in the standard: consteval functions that are guaranteed to run at compile time, which came from the reflection work and are designed specifically to be used to manipulate reflection information.

但是,有许多证据并不那么清楚地证明这一事实。

来自cppreference :

consteval - specifies that a function is an immediate function, that is, every call to the function must produce a compile-time constant.

这并不意味着它必须仅在编译时调用。

来自the P1073R3 proposal :

There is now general agreement that future language support for reflection should use constexpr functions, but since "reflection functions" typically have to be evaluated at compile time, they will in fact likely be immediate functions.

好像是这个意思,但还是没说清楚。来自同一提案:

Sometimes, however, we want to express that a function should always produce a constant when called (directly or indirectly), and a non-constant result should produce an error.

同样,这并不意味着该函数必须仅在编译时进行评估。

来自this answer :

your code must produce a compile time constant expression. But a compile time constant expression is not an observable property in the context where you used it, and there are no side effects to doing it at link or even run time! And under as-if there is nothing preventing that

最后,there is a live demo ,其中 consteval 函数显然是在运行时调用的。但是,我希望这是由于 clang 中尚未正确支持 consteval 且行为实际上是不正确的,就像 Why does a consteval function allow undefined behavior? 中那样。

更准确地说,我想听听所引用文章的以下哪些陈述是正确的:

  1. 立即函数仅在编译时可见(无法在运行时求值)
  2. 立即函数不会发出符号
  3. 调试器等工具将无法立即显示功能

最佳答案

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

这些几乎都不是 C++ 标准能够给出的答案。该标准没有定义“符号”或可以显示哪些工具。就标准而言,几乎都是经销商的选择。

事实上,甚至“编译时”与“运行时”的问题也是标准没有处理的。与标准有关的唯一问题是某物是否是常量表达式。调用 constexpr 函数可能生成一个常量表达式,具体取决于其参数。以不产生常量表达式的方式调用 consteval 函数是错误格式的。

标准所做定义的一件事是“看到”的内容。虽然这并不是真正的“编译时间”。 C++20 中有许多语句禁止大多数函数处理对立即函数的指针/引用。例如,C++20 在 [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.

因此,如果您不在立即函数中,或者您没有使用立即函数的名称来调用另一个立即函数(传递对该函数的指针/引用),则无法命名立即函数。如果不命名函数,您就无法获得指向该函数的指针/引用。

规范中的此语句和其他语句(如 pointers to immediate function not being valid results of constant expressions )本质上使得对立即函数的指针/引用不可能泄漏到常量表达式之外。

因此,关于立即函数可见性的陈述在某种程度上是正确的。符号可以为立即函数发出,但是您不能以阻止实现丢弃所述符号的方式使用立即函数。

这基本上就是 consteval 的事情。它不使用标准语言来强制执行必须发生的事情。它使用标准语言使得无法以防止这些事情发生的方式使用该函数。所以更合理的说法是:

  1. 使用立即函数的方式不能阻止编译器在编译时执行它。

  2. 使用立即函数时不能阻止编译器丢弃其符号。

  3. 您不能以强制调试器能够看到它们的方式使用即时函数。

预计实现质量将从那里开始。

还应该注意的是,调试构建是为了......调试。高级编译器工具能够调试生成常量表达式的代码是完全合理的。因此,可以立即执行函数的调试器是一项完全理想的技术。随着编译时代码变得更加复杂,这种情况变得更加严重。

关于c++ - 编译器是否允许在运行时调用立即(consteval)函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58466245/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com