在函数范围内的const静态变量的情况下的内存分配

时间:2013-01-12 23:00:21

标签: c memory memory-management static

在C中,static const intconst int在内存分配方面有什么区别?

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

    *a = b + c;
}

b只会消耗sizeof(int)吗? csizeof(int)值和20消耗sizeof(int)f执行期间是否会使用复制指令?

4 个答案:

答案 0 :(得分:5)

语言标准对此没有任何说明。

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

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

因此根本不分配任何内存(显然除了指令空间)。

答案 1 :(得分:1)

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

每次进入函数时,函数内的

const int将在堆栈上分配,并在退出时从堆栈中释放。

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

答案 2 :(得分:1)

鉴于函数内部已知两个常量,是什么阻止编译器使其成为*a = 30;?在这个例子中,bc都必须有存储空间。

如果需要存储空间:

 static const int b = 10;

将占用一个sizeof(int)[由于填充可能使用更多空间,取决于数据部分中{I}之前和之后的内容,并且没有任何内容表明编译器将提供多少填充对于任何给定的场景 - 在编译器所针对的系统上使事情“起作用”的任何必要条件]。根据系统的体系结构,可能需要设置b = 10的代码[见下面的大小]。

a

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

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

答案 3 :(得分: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;
}