可以說我有兩個文件:命名空間和靜態類成員聯
/**
* class.cpp
*/
#include <stdio.h>
class foo
{
private:
int func();
};
int foo::func(void)
{
printf("[%s:%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
return -1;
}
和
/**
* main.cpp
*/
#include <stdio.h>
namespace foo
{
int func(void);
}
int main(void)
{
int ret = foo::func();
printf("[%s:%d]: ret=%d\n", __FILE__, __LINE__, ret);
return 0;
}
編譯如下:
g++ -o a.out main.cpp class.cpp
有一個從可執行文件的輸出:
[class.cpp:15]: func
[main.cpp:14]: ret=-1
最後我的問題:
爲什麼這個示例代碼編譯沒有任何錯誤,我們都能夠調用私有方法類Foo的?
編譯與gcc 4.6.3但不僅。 我知道,編譯器並不區分這兩個符號(從命名空間富和私有函數富從類FooFUNC功能)。從納米輸出:
nm class.o
00000000 T _ZN3foo4funcEv
00000017 r _ZZN3foo4funcEvE12__FUNCTION__
U printf
nm main.o
U _ZN3foo4funcEv
00000000 T main
U printf
我想問一下這種行爲是否正確與否?恕我直言,這是不正確的行爲,它是不安全的(打破封裝)。
我想提一下,visual studio 2008的編譯器不會鏈接這兩個符號。
好的,我明白一切,但問題是爲什麼有這樣的gcc編譯器的行爲。 Windows編譯器能夠區分這些符號。命名空間和類是不一樣的,我願意嗎?編譯器應該知道命名空間和類之間的所有區別,不是嗎? – pako 2013-03-20 20:11:30
編譯器知道,但鏈接器不知道。但是,編譯器會將每個文件轉換爲單獨的對象文件。您定義這兩個文件的方式是它們與編譯器完全分離。 VS做的很好,但不需要做。因此,不是由gcc完成的。鏗鏘也編譯這沒有抱怨的方式。 – meyumer 2013-03-20 20:15:54
我知道編譯器知道,但我的意思是編譯器爲這些函數生成完全相同的符號,即使它們完全不同。所以也許gcc應該和VS編譯器一樣?它可以避免一些潛在的錯誤。 – pako 2013-03-20 20:23:34