【问题标题】:Memory allocation in case of const static variables in function scope函数范围内 const 静态变量的内存分配
【发布时间】:2013-01-12 23:00:21
【问题描述】:

在 C 中,static const intconst 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 执行期间的复制指令?

【问题讨论】:

    标签: c memory memory-management static


    【解决方案1】:

    语言标准对此只字未提。

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

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

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

    【讨论】:

      【解决方案2】:

      鉴于这两个常量在函数内部都是已知的,有什么可以阻止编译器将其设为*a = 30;?在此示例中,bc 都不得有存储空间。

      如果需要存储:

       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 以某种方式。其他一切都“取决于编译器”。

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

        • 如果 OP 的代码是字面上写的,那么它确实可以像我的回答一样“转换”。
        • 我的 gcc (4.6.2) 和 clang (3.0) 从-O 开始删除它。
        • 是的。我想我更多的是解决问题的存储类问题角度,而不是提供的代码。
        【解决方案4】:

        在您的示例中,它们的含义相同,正如@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;
        }
        

        【讨论】:

        • 这个用例我已经知道了,我想知道定义“真实”常量时的内存消耗。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-23
        • 1970-01-01
        • 2013-11-10
        • 2011-06-11
        • 2023-03-02
        • 2012-06-06
        相关资源
        最近更新 更多