![](/img/trans.png)
[英]What is the use of declaring a static variable as extern inside a function?
[英]Declaring a function level static variable inside an if block that is never hit
我對函數內部聲明的靜態變量的理解是:
.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
沒有創建foo_var_in_0
(可能是因為它在顯式if(0)
),而bar_var_in_0
被創建(因為調用者可以傳遞非零值 - 盡管唯一的調用者顯式傳遞零)。
我想我的問題是:假設根本沒有為變量foo_var_in_0
分配內存是否正確? 我在問這個具體案例; 我是否正確地閱讀了objdump - 或者我應該做更多的事情來驗證變量是否會在程序運行時占用一些內存?
換句話說,如果從未命中聲明函數級靜態變量的行,那么變量實際上是否已聲明?
如果它根本不會被創建,那么這是根據C標准(不太可能),還是編譯時優化以及在什么級別 - 如何將其打開/關閉(在gcc 4.1.1中)?
我知道一個int並不是一個值得關注的大問題,但我對它的工作原理更感興趣; 如果變量是一個大的數組,比如一個10字節結構的5000個元素,該怎么辦?
假設根本沒有為變量foo_var_in_0分配內存是否正確?
不,我不認為這是正確的。 據我所知,這樣的優化不是標准的一部分。
如果您知道編譯器執行此操作並且您想要假設它,請繼續。 如果您編寫需要這樣的任何內容,您可能需要編寫一個構建后測試以確保它發生。
也許,你所看到的是編譯器的副作用,只是修剪了一些它知道永遠不會運行的代碼。 意思是,它不是專門想要刪除靜態,但它確實刪除了整個分支,因此其中的任何代碼也被刪除了。
C標准沒有規定放置變量和內容的位置。 它只是規定符合要求的實現應具有等效行為(對於標准規定的參考行為),其中“等效”也由標准定義。
所以簡單的答案是它是一個優化,如何打開/關閉它取決於特定的編譯器。
進行過程間分析的實現可能也可以擺脫bar_var_in_0
。
只是為了增加其他人的正確答案。 關於static
變量初始化的假設是不正確的。
0
隱式提供,則顯式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.