次の 2 つのファイルがあるとします。
/**
* 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 でコンパイルされていますが、それだけではありません。私は、コンパイラがこれら 2 つのシンボル (名前空間fooのfunc関数とクラス fooのプライベート関数foo )を区別しないことを知っています。nmからの出力:
nm class.o
00000000 T _ZN3foo4funcEv
00000017 r _ZZN3foo4funcEvE12__FUNCTION__
U printf
nm main.o
U _ZN3foo4funcEv
00000000 T main
U printf
この振る舞いが正しいかどうかお聞きしたいです。IMHOこれは正しい動作ではなく、まったく安全ではありません(カプセル化を壊します)。
Visual Studio 2008 のコンパイラは、これら 2 つのシンボルをリンクしていません。