我只是想知道const int N=10
之类的句子是否会在编译时执行。我问的原因是因为以下代码可以正常工作。
int main()
{
const int N=10;
int a[N]={};
return 0;
}
但是这个人不会。
int main()
{
int N=10;
int a[N]={};
return 0;
}
答案 0 :(得分:7)
编译器必须生成代码“好像”表达式的计算结果
编译时间,但const
本身不足以满足要求。在
以便用作数组的维度,例如,表达式
N
必须是“常量积分表达式”。 const int
是。{
只有在用常量初始化时才是常量积分表达式
积分表达式,初始化对编译器可见。
(例如,extern int const N;
之类的东西不能用于
一个恒定的积分表达式。)
要成为常量积分表达式,变量必须是
const
;在你的第二个例子中,编译器的行为和
结果程序必须“好像”表达式仅在
运行时(这意味着它不能用作一个维度
数组)。在实践中,至少在优化时,编译器很可能
会在编译时评估N
,但它仍然必须假装它
不能,并拒绝编译代码。
答案 1 :(得分:2)
编译器可能会评估您在编译时提供的两个示例,因为即使int N = 10;
不是const
,您也不会在任何地方更改它并且您&# 39;仅为其分配一个常量值,这意味着编译器可以优化它。
我建议你看一下C ++ 11中引入的constexpr
关键字,它完全是关于能够在编译时评估事物。
答案 2 :(得分:1)
编译器将在编译时将const变量解析为文字(以及const表达式,请参阅constant folding)。第一种方法有效的原因是编译器知道在第一种方法中要分配多少空间(10 * sizeof(int))。在第二种方法中,N的值在编译时是未知的,因此编译器无法知道为a分配多少空间。希望有所帮助。
答案 3 :(得分:1)
这种事情是一个实现细节,技术上由编译器来决定。它可能在不同的平台上有所不同。
在实践中,使用最常见的编译器:
const int 有时会在编译时被烘焙。例如,编译器显然无法将下面a
的值硬编码到目标文件中:
int foo( int x )
{
const int a = x+ 1;
return a * 2;
}
在该函数中,const
表示它仅在foo()范围内是常量,但它仍然是本地堆栈变量。
另一方面,const int x = 5
似乎是一个通常由GCC和MSVC在编译时解决的文字(除了有时他们不会因为不清楚的原因而将其变成文字)。我已经看到一些其他编译器不会将它变成文字,并且总是将const int
放在堆栈上,就像普通的局部变量一样。
const static int 是不同的,因为它的范围是静态的,这意味着它比它声明的函数更长,这意味着它永远不会改变它的生命周期该程序。我曾经使用的每个编译器都将 const static 原语转换为编译时文字。
但是,构造函数的对象仍然需要在运行时初始化;所以
class Foo {
Foo() : { CallGlobalFunction(); }
};
const static Foo g_whatever;
无法由编译器优化为文字。