2012-10-15 35 views
0

有一天,我正在將一個用C99標準編寫的程序轉換成C11。基本上動機是使用MSVC的代碼,但它是用Linux編寫的,並且大部分都是使用默認的GCC行爲編譯的。在代碼轉換過程中,我發現你不能在任何語句後去除函數的變量,也就是說你必須在函數的頂部聲明它們。使用C99和C11時的效率問題。

但我的問題是,它不會違反有效的編程規則,變量應該在其使用附近進行聲明,以使其最大化緩存命中?例如,在一個200 LOC的大函數中,我想在函數的最後使用一些大的靜態查找數組。在使用導致更多緩存命中之前不會聲明並初始化它?還是我簡單地缺少C11 C語言標準的一些基本點?

+0

C2011(我恨名字C11)允許與代碼混合的聲明。 *我明白微軟的編譯器只能理解C89,可能只有一些擴展。* – pmg

+1

這與C89有關,在這裏你不能在同一個塊中的語句之後放置聲明。 C99和C11中不再存在此要求。 – ouah

+1

MSVC不支持C11。也許你的意思是C89? – ecatmur

回答

4

您似乎對編譯程序的哪個版本的標準有些疑惑。 AFAIK,MSVC不支持任何更新的C標準。

但是,要回到您的問題的核心,這不是一個效率問題。只要程序的可觀察行爲不改變,編譯器就可以按照自己的喜好重新排列語句。因此,一個現代編譯器會在第一次使用之前總是觸及一個新的變量。

+0

除非涉及volatile,否則可能在函數的開頭有一個純聲明,根本不可訪問該變量。 –

+0

@BenVoigt,'volatile'對於語句的重新排序沒有太大的影響,我想。它只強制爲每個使用它的表達式重新加載一個對象。什麼可能影響編譯器可以推斷出的是別名。但是一般來說,如果你在你的程序開始時聲明一個int變量,甚至初始化它,編譯器可以在第一次使用該變量之前的任何地方進行初始化。 –

+1

* other *變量的讀取和寫入不能跨越易失性訪問進行移動。 –

2

變量聲明出現的位置對緩存行爲沒有影響。只是有一個聲明不會觸及內存。

但是,您可能需要將初始化劃分爲單獨的賦值,以確保在函數的開頭(靠近)沒有引起內存訪問的初始化程序。