關於靜態函式我相信大家一定不會陌生,在專案中多多少少也會去使用,靜態函式的典型應用場景莫過於限制函式的作用域只在本檔案中,在我見過的專案中通常開發人員會把一些輔助函式放在標頭檔案中,然後直接包含到專案中,如果不用static修飾會導致函式重定義(這其實很不規範,偷懶的把檔案的宣告和定義都放到了標頭檔案中,正規的做法應該是宣告放在標頭檔案中,定義放在實現檔案中)。
// static.h
#include
static
void test()
#endif
例如上面這個標頭檔案來說,如果不用static修飾test函式,那麼當有多個檔案包含static.h會導致函式重定義的問題,通過新增static關鍵字會將這個函式變成區域性符號只在這個檔案中可見。儘管這種方式很不規範,但是依舊可以正常工作著,直到有一天有個人寫了下面這段**。
// static.h
static
void test()
上面這個函式通過靜態變數data來控制讓某些事情只做一次。然後這個test函式在多個檔案中被呼叫。
// a.cc
#include "static.h"
void test1()
// b.cc
#include "static.h"
void test2()
很不幸上面的**不能正常的work,test1和test2都呼叫了靜態函式test,但是兩次執行的時候靜態變數data的值都是0,很明顯這是不符合預期的。造成這一現象的原因是因為a.cc和b.cc分別都包含了static.h,導致test函式的定義存在兩份,其包含的靜態變數也存在了兩份,通過g++ -s檢視兩個檔案的彙編可以驗證這個事實。
.file
"a.cc"
.text
.type _zl4testv, @function
_zl4testv: //test函式額實現
.lfb0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl _zzl4testve4data(%rip), %eax
testl %eax, %eax
jne .l1
movl $1, _zzl4testve4data(%rip)
.l1:
popq %rbp
.cfi_def_cfa 7, 8
ret.cfi_endproc
.....
b.cc的彙編同樣也包含了靜態函式test的定義,這說明了test函式的定義存在兩份,也就驗證了為什麼會出現上面的結果了,只要有檔案包含了static.h就會導致這個函式的的定義多存在乙份實現。不僅導致了**膨脹,結合靜態變數的情況下,還導致了未定義的行為。 都是 IDENTITY惹的禍
前不久系統伺服器出現了一次不大不小事故,資料庫乙個表的資料不翼而飛,這個表雖然算不上頂級重要的表,但也算的上是個很重要的表,大家趕緊查是什麼把這個表的資料刪的只剩下180多條資料.為什麼還有180多條資料存在哪?真是挺讓人納悶的,但發現這180多條資料中有乙個共性,那就是那個不該為空的字段變成了空值...
都是埠惹的禍
這幾天公司搬家,所以忙的blog好久都沒有更新,關鍵是沒有什麼技術上的事情,都不知道寫點什麼,呵呵。周四到週日一直在乙個客戶那邊進行產品的實施,整個過程自然比較有趣,對於我來說最重要的就是認識到了靈活程式設計的重要。我們的程式需要幾個通訊埠,其中乙個是1433用來連線sqlserver資料庫,很多的...
都是埠惹的禍
這幾天公司搬家,所以忙的blog好久都沒有更新,關鍵是沒有什麼技術上的事情,都不知道寫點什麼,呵呵。周四到週日一直在乙個客戶那邊進行產品的實施,整個過程自然比較有趣,對於我來說最重要的就是認識到了靈活程式設計的重要。我們的程式需要幾個通訊埠,其中乙個是1433用來連線sqlserver資料庫,很多的...