精華區beta C_and_CPP 關於我們 聯絡資訊
如標題 據我理解 static global的變數 寫在.h 然後include這.h的file都擁有一份 這名稱的變數 如果這.h 裡面是用 namespace { int x;}把東西包起來 據我理解 效果跟static global變數 是一樣的 請教各位兩者差異 以及哪個寫法比較好... 我印象中 有人說namespace的寫法比較好~~但是我爬不太到文章 謝謝各位 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.113.207.187
QQ29:15482 有提到 可是這兩者是不是沒差別? 09/04 15:33
> -------------------------------------------------------------------------- < 作者: tinlans ( ) 看板: C_and_CPP 標題: Re: [問題] static global 變數 跟 無名的namespac … 時間: Fri Sep 4 16:33:41 2009 ※ 引述《QQ29 (我愛阿蓉)》之銘言: : 如標題 : 據我理解 : static global的變數 寫在.h 然後include這.h的file都擁有一份 這名稱的變數 : 如果這.h 裡面是用 : namespace { int x;}把東西包起來 : 據我理解 效果跟static global變數 是一樣的 : 請教各位兩者差異 以及哪個寫法比較好... : 我印象中 有人說namespace的寫法比較好~~但是我爬不太到文章 : 謝謝各位 如果你有使用一些 library 所以 #include 了一堆 header files, 你用 global static 還是可能跟它的名稱發生衝突, 像是 basename() 這東西在 <libgen.h> 有宣告, 你如果自己寫的 code 有定義一個 local 的 basename(), 那就會出現宣告式/定義式不一致的 error (一個有 static 一個沒有就會 error), 你用 anonymous namespace 就不會有這問題。 不過在 header file 使用 static 或 anonymous namespace 都不是好習慣, 在 header file 裡開 anonymous namespace 放 functor 也是不正確的做法, GCC 4.2 以後的行為可能會讓有這些習慣的人大吃一驚, 因為 hidden 的 visibility 屬性會隨 template 參數傳遞下去。 > -------------------------------------------------------------------------- < 作者: QQ29 (我愛阿蓉) 看板: C_and_CPP 標題: Re: [問題] static global 變數 跟 無名的namespac … 時間: Sat Sep 5 03:14:25 2009 ※ 引述《tinlans ( )》之銘言: : ※ 引述《QQ29 (我愛阿蓉)》之銘言: : : 如標題 : : 據我理解 : : static global的變數 寫在.h 然後include這.h的file都擁有一份 這名稱的變數 : : 如果這.h 裡面是用 : : namespace { int x;}把東西包起來 : : 據我理解 效果跟static global變數 是一樣的 : : 請教各位兩者差異 以及哪個寫法比較好... : : 我印象中 有人說namespace的寫法比較好~~但是我爬不太到文章 : : 謝謝各位 : 如果你有使用一些 library 所以 #include 了一堆 header files, : 你用 global static 還是可能跟它的名稱發生衝突, : 像是 basename() 這東西在 <libgen.h> 有宣告, : 你如果自己寫的 code 有定義一個 local 的 basename(), : 那就會出現宣告式/定義式不一致的 error (一個有 static 一個沒有就會 error), : 你用 anonymous namespace 就不會有這問題。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ T大您好 針對這個我去測試一下 VC8 我在.h寫 namespace {void foo(){}} .cpp那邊 再次定義 void foo(){} main裡面呼叫foo就會 compile error說 : 模稜兩可的呼叫多載函式 兩個問題請教 1. 為啥出錯是在呼叫foo才會錯 我不呼叫 難道他就不編譯嘛?? 不是很了解原理@@ 2. 我這測試是否是您說的情況 謝謝你 > -------------------------------------------------------------------------- < 作者: tinlans ( ) 看板: C_and_CPP 標題: Re: [問題] static global 變數 跟 無名的namespac … 時間: Sat Sep 5 04:04:34 2009 ※ 引述《QQ29 (我愛阿蓉)》之銘言: : ※ 引述《tinlans ( )》之銘言: : : 如果你有使用一些 library 所以 #include 了一堆 header files, : : 你用 global static 還是可能跟它的名稱發生衝突, : : 像是 basename() 這東西在 <libgen.h> 有宣告, : : 你如果自己寫的 code 有定義一個 local 的 basename(), : : 那就會出現宣告式/定義式不一致的 error (一個有 static 一個沒有就會 error), : : 你用 anonymous namespace 就不會有這問題。 : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ : T大您好 : 針對這個我去測試一下 : VC8 : 我在.h寫 namespace {void foo(){}} : .cpp那邊 : 再次定義 void foo(){} : main裡面呼叫foo就會 compile error說 : 模稜兩可的呼叫多載函式 : 兩個問題請教 : 1. 為啥出錯是在呼叫foo才會錯 : 我不呼叫 難道他就不編譯嘛?? : 不是很了解原理@@ 本來就是呼叫才會錯, anonymous namespace 跟 global 又不是同個 namespace, 只是在呼叫的時候會同時看見而已, 不代表不能這樣寫; 因為 main() 同時間看到兩個 foo(), 你沒有指定要呼叫誰當然會出現 ambiguous。 正常狀況來說不會有人這樣寫, 因為會起名稱衝突的大都是來自 library, library 提供的大都是功能簡單的小函式, 一般來說不可能會直接被 main() 使用, 所以通常會有一個更大的函式也被放在 anonymous namespace 裡, 然後這個大函式會被 main() 直接呼叫, 比方說: namespace { void Action1() { ... } void Action2() { ... } void Action3() { ... } void BigFunction() { Action1(); Action2(); Action3(); } } int main() { BigFunction(); } 一般來說 BigFunction 的命名很難取到跟 library 衝突, 會衝的通常都是更底層的小 function, 所以這樣寫就能自然迴避上述的 ambiguous 問題, 你就算在 global 裡面也放了 Action1() 的宣告式或定義式, BigFunction() 還是會呼叫到 anonymous namespace 的 Action1(), 不過前提是至少 local 版的 Action1() 宣告式有出現在 BigFunction() 定義式之前, 否則還是會有意外。 總之你的問題在實際的程式幾乎不會遇到。 : 2. 我這測試是否是您說的情況 我說的情況是假設某個 library 提供的 header 長這樣: // lib.h ... void foo(); // 等同 extern void foo(); ... 然後你自己寫的某個檔案長這樣: #include "lib.h" static void foo() { ... } 這樣是無法通過編譯的, 因為 lib.h 裡面是 extern 而你自己寫的檔案又把標上 static, 所以就會 error, 但是這時候你寫成這樣就不會有事: #include "lib.h" namespace { static void foo() { ... } } 當然如果是你一開始舉的那種小例子還是會有 ambiguous 的問題, 可是只要寫程式的習慣良好就不會遇上那種事, 小測試遇上是難免的, 不然除非是有一個 function 就塞 10 萬行 code 的習慣, 這種人才比較有機會遇上你前面描述的問題。