我对函数内声明的静态变量的理解是:
.bss
中,否则将位于.data
main
之前
但是如果我在if
块中声明我的静态变量怎么办?我假设我的第三点应该更新为“当执行到达声明静态变量的行时,它们被初始化为......” - 我是否正确?
现在,如果它们被声明的if
块从未被命中(并且编译器能够解决这个问题),那么我知道该变量永远不会被初始化;但是为该变量分配了任何内存吗?
我写了两个函数来试图弄清楚发生了什么:
#include <stdio.h>
void foo()
{
static foo_var_out;
if(0){
static foo_var_in_0;
printf("%d %d\n", foo_var_in_0);
} else {
static foo_var_in_1;
printf("%d %d\n", foo_var_in_1);
}
}
static void bar(int flag)
{
static bar_var_out;
if(flag){
static bar_var_in_0;
printf("%d %d\n", bar_var_in_0);
} else {
static bar_var_in_1;
printf("%d %d\n", bar_var_in_1);
}
}
int main()
{
foo();
bar(0);
}
我接受了对象转储:
$ gcc -o main main.c
$ objdump -t main | grep var
45:080495c0 l O .bss 00000004 foo_var_in_1.1779
46:080495c4 l O .bss 00000004 foo_var_out.1777
47:080495c8 l O .bss 00000004 bar_var_in_1.1787
48:080495cc l O .bss 00000004 bar_var_in_0.1786
49:080495d0 l O .bss 00000004 bar_var_out.1785
从输出看起来根本没有创建foo_var_in_0
(大概是因为它在显式if(0)
内),而bar_var_in_0
被创建(因为调用者可能)传递非零值 - 尽管唯一的调用者显式传递零。)
我想我的问题是:假设根本没有为变量foo_var_in_0
分配内存是否正确?我在问这个具体案例;我是否正确地阅读了objdump - 或者我应该做些什么来验证变量是否会在程序运行时占用一些内存?
换句话说,如果从未命中声明函数级静态变量的行,那么实际上是否声明了变量?
如果它根本不会被创建,这是根据C标准(不太可能),还是编译时优化以及在什么级别 - 如何将其打开/关闭(在gcc 4.1.1中)?
我知道一个int并不是什么值得关注的事情,但我对它的工作原理更感兴趣;如果变量是一个大的数组,比如一个10字节结构的5000个元素呢?
答案 0 :(得分:3)
假设根本没有为变量foo_var_in_0分配内存是否正确?
不,我不认为这是正确的。据我所知,这样的优化不是标准的一部分。
如果您知道编译器执行此操作并且您想要假设它,请继续。如果您编写任何需要这种情况的内容,您可能需要编写一个构建后测试以确保它发生。
你可能看到的是编译器的副作用,只是修剪了一些它知道永远不会运行的代码。意思是,它不是专门想要删除静态,但它确实删除了整个分支,因此其中的任何代码也被删除了。
答案 1 :(得分:2)
C标准没有规定放置变量和内容的位置。它只是规定符合要求的实现应具有等效行为(对于标准规定的参考行为),其中“等效”也由标准定义。
所以简单的答案就是它是一种优化,如何打开/关闭它取决于特定的编译器。
执行过程间分析的实现可能也可以摆脱bar_var_in_0
。
答案 2 :(得分:2)
只是为了添加其他人的正确答案。您对static
变量初始化的假设不正确。
0
。