static 是否将自动变量中的任何内容更改为 const?
Does a static change anything to const in an automatic variable?
考虑以下定期调用的函数:
void func(void)
{
const int myConstArray[4] = {1, 2, 3, 4};
// Doing some operations including the above array
}
如果将 myConstArray
从 const
更改为 static const
,这是否会改变代码的编译方式?
将const
更改为static const
会更改对象的存储期限。当数组在函数内声明 const int myConstArray[4] = {1, 2, 3, 4};
时,它具有 自动 存储持续时间,这意味着从其关联块的执行开始到执行块结束。将声明更改为 static const int myConstArray[4] = {1, 2, 3, 4};
会为其提供 static 存储持续时间,这意味着为整个程序保留内存。
现在,如果程序不使用更长的存储持续时间,则编译器不必做任何不同的事情。考虑这段代码:
int foo(int x)
{
static const int Table[] = { 1, 5, 3, 6 };
return Table[x];
}
在这段代码中,编译器可以看出Table
只是用来查找一个值的。因此,当函数不执行时它不需要存在——无论是否为 Table
保留内存,程序的行为都是一样的,所以它是否被声明为 static
并不重要.
将其与此代码进行比较:
int foo(int x)
{
static const int Table[] = { 1, 5, 3, 6 };
bar(Table);
return Table[x];
}
这里函数将Table
的地址传递给bar
。编译器不知道 bar
将对该地址做什么。 bar
可能会存储地址,稍后在程序中由其他例程使用。在这种情况下,Table
是否为 static
很重要。如果 Table
不是 static
,它的生命周期不会超出 foo
的执行时间,所以它的地址以后不应该被使用(如果是,程序行为没有被定义C标准)。这意味着编译器可以为 Table
使用堆栈 space。但是,如果Table
和static
一起声明,它的地址可以在foo
执行后使用,所以即使foo
执行结束,编译器也必须为它预留内存。
最后,考虑这段代码:
int foo(int x)
{
const int Table[] = { 1, 5, 3, 6 };
bar(Table);
return Table[x];
}
由于Table
没有声明static
,所以每次调用foo
时,里面的Table
在C标准的语义上是一个新的对象。此外,所有不同的对象必须具有不同的地址(包含对象开头的子对象除外,例如数组及其第一个元素或结构及其第一个成员)。因此,如果 bar
递归调用 foo
,则会创建第二个 Table
并再次调用 bar
。由于两个 Table
对象必须不同,因此 bar
必须传递不同的地址。这意味着,在 Table
未声明 [=19=] 的情况下,每次调用 foo
时,编译器可能被迫在堆栈上创建它的新实例。为避免这种情况,最好用 static
.
声明 Table
考虑以下定期调用的函数:
void func(void)
{
const int myConstArray[4] = {1, 2, 3, 4};
// Doing some operations including the above array
}
如果将 myConstArray
从 const
更改为 static const
,这是否会改变代码的编译方式?
将const
更改为static const
会更改对象的存储期限。当数组在函数内声明 const int myConstArray[4] = {1, 2, 3, 4};
时,它具有 自动 存储持续时间,这意味着从其关联块的执行开始到执行块结束。将声明更改为 static const int myConstArray[4] = {1, 2, 3, 4};
会为其提供 static 存储持续时间,这意味着为整个程序保留内存。
现在,如果程序不使用更长的存储持续时间,则编译器不必做任何不同的事情。考虑这段代码:
int foo(int x)
{
static const int Table[] = { 1, 5, 3, 6 };
return Table[x];
}
在这段代码中,编译器可以看出Table
只是用来查找一个值的。因此,当函数不执行时它不需要存在——无论是否为 Table
保留内存,程序的行为都是一样的,所以它是否被声明为 static
并不重要.
将其与此代码进行比较:
int foo(int x)
{
static const int Table[] = { 1, 5, 3, 6 };
bar(Table);
return Table[x];
}
这里函数将Table
的地址传递给bar
。编译器不知道 bar
将对该地址做什么。 bar
可能会存储地址,稍后在程序中由其他例程使用。在这种情况下,Table
是否为 static
很重要。如果 Table
不是 static
,它的生命周期不会超出 foo
的执行时间,所以它的地址以后不应该被使用(如果是,程序行为没有被定义C标准)。这意味着编译器可以为 Table
使用堆栈 space。但是,如果Table
和static
一起声明,它的地址可以在foo
执行后使用,所以即使foo
执行结束,编译器也必须为它预留内存。
最后,考虑这段代码:
int foo(int x)
{
const int Table[] = { 1, 5, 3, 6 };
bar(Table);
return Table[x];
}
由于Table
没有声明static
,所以每次调用foo
时,里面的Table
在C标准的语义上是一个新的对象。此外,所有不同的对象必须具有不同的地址(包含对象开头的子对象除外,例如数组及其第一个元素或结构及其第一个成员)。因此,如果 bar
递归调用 foo
,则会创建第二个 Table
并再次调用 bar
。由于两个 Table
对象必须不同,因此 bar
必须传递不同的地址。这意味着,在 Table
未声明 [=19=] 的情况下,每次调用 foo
时,编译器可能被迫在堆栈上创建它的新实例。为避免这种情况,最好用 static
.
Table