有一條規則規定,不應在C或C++中定義或使用以下劃線開頭且後跟大寫的標識符(例如, _Foo
。這是因爲這些標識符是由編譯器保留的,因此可能會與某些編譯器代碼發生衝突並導致未定義的行爲。由標識符以下劃線開始導致的錯誤的現實示例
雖然這個規則是衆所周知的,並被許多編碼標準所採用,但我從來沒有見過這種規則可以防止很多損害的真實生活情況。
有人知道一個違反此規則的真實案例嗎?編輯:我正在談論的代碼,編譯和鏈接很好,但由於這個顯示意外的行爲。
有一條規則規定,不應在C或C++中定義或使用以下劃線開頭且後跟大寫的標識符(例如, _Foo
。這是因爲這些標識符是由編譯器保留的,因此可能會與某些編譯器代碼發生衝突並導致未定義的行爲。由標識符以下劃線開始導致的錯誤的現實示例
雖然這個規則是衆所周知的,並被許多編碼標準所採用,但我從來沒有見過這種規則可以防止很多損害的真實生活情況。
有人知道一個違反此規則的真實案例嗎?編輯:我正在談論的代碼,編譯和鏈接很好,但由於這個顯示意外的行爲。
我工作的系統中,我們的應用程序代碼有一個函數_bind()
(用於綁定SQL語句中的主機變量),它沒有變成靜態的,因此它是公開的。
在一個O的一個版本(至少)/ S(我忘了,這一切都是在上個千年),該系統提供的功能_bind()
這 - 驚喜,驚喜 - 有不同的接口,並做了一個不同作業(將套接字綁定到IP地址或其附近)。當應用程序代碼與系統庫鏈接時,系統庫代碼在嘗試建立網絡連接時最終調用_bind()
函數。事情進展不順利。
我們重命名了該函數或將其設爲靜態(或兩者)並且問題消失了。現代共享庫可以最大限度地減少發生這種事情的可能性。我們的代碼使用了靜態庫,我認爲O/S也使用了靜態C庫(很久以前!)。使用共享庫會改變動態。
遺漏了大量模糊細節的僞信息 - 這種情況往往是一個暫時的問題,因爲人們很快修復它們。
'_bind'(不像例如'_Bind'或'__bind')不會被保留用於實現,這是一個OS函數,而不是一個標準函數。當包含操作系統頭文件(WinDef.h任何人?)時,可能會發生各種不好的事情,這些都未包含在語言標準中。 –
@ArneVogel標識符以下劃線開始(不一定是後跟一個大寫字母)在全局範圍內保留(如果有內存服務的話)。 – Quentin
以下劃線和小寫字母開頭的應用程序標識符在文件範圍內有效。 「這通常是通過使用前綴(通常是一個或多個下劃線)完成的,C和C++在這方面值得注意:C99保留以兩個下劃線或下劃線開頭並帶有大寫字母的標識符,並進一步保留以在文件範圍內使用一個下劃線(在普通和標記空間中); [1]使用C++ 03進一步保留包含任何地方的雙下劃線的標識符「來源:https://en.wikipedia.org/wiki/Reserved_word #Reserved_ranges –
如果存在名稱衝突,那麼應該在編譯時檢測到它,而不是在運行時檢測到崩潰或其他UB。 –
此外,還會保留任何位置包含兩個連續下劃線「__」的標識符名稱。 –
我在這裏看到了幾個問題,這些問題歸結爲一個系統頭文件被跳過,因爲程序員使用一個保留名稱作爲包含守護宏,並以系統頭已使用的相同名稱結束。不過,這不是一個容易搜索的問題。 –