繁体   English   中英

在编译时知道什么值?

[英]What is a value known at compile time?

我正在学习C ++编程语言,在一章中我的书向我介绍了常量的概念:

必须为constexpr符号常量指定在编译时已知的值

在编译时知道什么值? 我们为什么需要它们?

常量表达式表示可以在编译时在编译时(即在程序运行之前,在编译期间)计算的表达式。

常量表达式可用于初始化用constexpr标记的变量( 参考C ++ 11概念 )。 这样的变量为编译器提供了可以进行编译时评估的提示(并且可以节省宝贵的运行时间),例如

#include <iostream>

constexpr int factorial(int n) // Everything here is known at compile time
{
    return n <= 1 ? 1 : (n * factorial(n - 1));
}

int main(void)
{
    constexpr int f = factorial(4); // 4 is also known at compile time
    std::cout << f << std::endl;
    return 0;
}

如果不提供常量表达式,编译器无法在编译时实际完成所有这些工作:

#include <iostream>

constexpr int factorial(int n) // Everything here is known at compile time
{
    return n <= 1 ? 1 : (n * factorial(n - 1));
}

int main(void)
{
    int i;
    std::cin >> i;
    const int f = factorial(i); // I really can't guess this at compile time..
                                // thus it can't be marked with constexpr
    std::cout << f << std::endl;
    return 0;
}

编译时额外工作而不是运行时工作的好处性能提升,因为编译后的程序可能能够使用预先计算的值而不必每次都从头开始计算它们。 常量表达式越昂贵,程序获得的收益就越大。

在编译时知道什么值?

我认为谈论常量表达更有意义。 常量表达式具有在编译时已知的值。 粗略地说,它可能只是一个文字,另一个变量的名称(其值在编译时也是已知的)或涉及在编译时已知值的子表达式的复杂表达式。

引用声明使用constexpr声明的变量的初始值设定项需要是常量表达式。 特别是表达必须满足的要求是一个常量表达式; 这些都列在这里

例子是

constexpr int i = 54;
constexpr float f = 684; // Compile-time conversion from int to float

constexpr int func( int i )
{
    return i*47 % 23;
}

constexpr auto value = func(i * f); // Okay; constexpr function called
                                    // with arguments that, when substituted inside,
                                    // yield constant expressions

有时在编译时实际知道一个值,但根据标准,表达式不是常量。 那包括

int i = 43;
constexpr int j = reinterpret_cast<int>(i); // Shouldn't compile. (Does with GCC)

有些情况下编译器可能会进行常量折叠 - 某些值可以在编译时计算但不一定是。

int i = 0;

for (int j = 1; j != 10; ++j)
    i += j;

return i;

只要行为保持不变,编译器就可以完全消除循环并用55初始化i (或简单地返回55并消除i )。 这被称为as -if规则

这意味着程序不需要运行以计算常量。 例如:

int num = 4;

您需要这些值,以便编译器将变量放在符号表中,程序可以在这些表中引用它们并使用它们。 对于常量,编译器将常量表示为无法更改的值。 因此,如果将常量声明为在运行时确定的某个常量,则它将不起作用,因为如果在编译时未定义常量,则它将保持未定义状态。 我希望这是有道理的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM