都是靜態函式惹的禍

2021-07-25 15:29:44 字數 1837 閱讀 2880

​ 關於靜態函式我相信大家一定不會陌生,在專案中多多少少也會去使用,靜態函式的典型應用場景莫過於限制函式的作用域只在本檔案中,在我見過的專案中通常開發人員會把一些輔助函式放在標頭檔案中,然後直接包含到專案中,如果不用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,test1test2都呼叫了靜態函式test,但是兩次執行的時候靜態變數data的值都是0,很明顯這是不符合預期的。造成這一現象的原因是因為a.ccb.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資料庫,很多的...