3

在 C 中,astatic const int和 aconst int在分配的内存方面有什么区别?

void f(int *a)
{
    static const int b = 10;
    const int c = 20;

    *a = b + c;
}

只会b消耗?sizeof(int)并且,它会在执行过程中c消耗sizeof(int)20,以及sizeof(int),加上复制指令吗?f

4

4 回答 4

5

语言标准对此只字未提。

但是,编译器很可能会将您的代码转换为:

void f(int *a) {
    *a = 30;
}

因此根本不分配内存(显然,指令空间除外)。

于 2013-01-12T23:01:56.883 回答
1

static const int 将在程序执行的整个生命周期内分配一次。

函数内部的 const int 将在每次进入函数时分配到堆栈上,并在退出时从堆栈中释放。

我可能会指出上面的“但是,编译器很可能会将您的代码转换为:”是不正确的。如果您请求“静态”存储类,则没有编译器会忽略这一点,静态变量可以指望在内存中传递指针 --- 除其他原因外。

于 2013-01-12T23:14:30.733 回答
1

鉴于这两个常量在函数内部都是已知的,那么是什么阻止编译器生成它*a = 30;?在此示例中,既不b也不c必须有存储。

如果需要存储:

 static const int b = 10;

将占用一个 sizeof(int) [由于填充可能会使用更多空间,这取决于a数据部分之前和之后的内容,并且没有说明编译器将为任何给定场景提供多少填充 - 无论是必要的使事情在编译器所针对的系统上“工作”]。根据系统的架构,可能需要设置 b = 10 的代码 [请参阅下面关于它的大小]。

 const int c = 20; 

可能会占用堆栈上的 sizeof(int) 个字节,但也会有代码初始化b为 20 - 可以是任何小的数字 - 2、3、5、6、7、8、16 或其他一些,具体取决于处理器架构和完成该工作所需的指令类型。当然,编译器可以在任何需要的地方直接使用 20。

但是编译器所需要的只是 *a 以某种方式设置为 30。其他一切都“取决于编译器”。

于 2013-01-12T23:24:50.387 回答
0

在您的示例中,它们的含义相同,并且正如@Oli 所提到的,编译器将对其进行优化,以使实际代码甚至可能在最终代码中都没有。

但这是不同的用例:-

int func1(int v) {
 const int c_i = compute_some_things(v);/* calculate the c_i everytime we enter this function */
 return c_i = v + c_i;
}


int func2(int e) {
 static const int c_i = compute_some_things_one_time();/* c_i is calculated ONCE, the next time, the value of c_i is retained every time the function is entered */
 return c_i = e + c_i;
}
于 2013-01-12T23:17:54.290 回答