→ 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 的習慣,
這種人才比較有機會遇上你前面描述的問題。
如標題
據我理解
static global的變數 寫在.h 然後include這.h的file都擁有一份 這名稱的變數
如果這.h 裡面是用
namespace { int x;}把東西包起來
據我理解 效果跟static global變數 是一樣的
請教各位兩者差異 以及哪個寫法比較好...
我印象中 有人說namespace的寫法比較好~~但是我爬不太到文章
謝謝各位
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.113.207.187