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
}

如果将 myConstArrayconst 更改为 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。但是,如果Tablestatic一起声明,它的地址可以在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