2009/05/20

C++ namespace -> undefined reference to 'main'

C++ の namespace は重要なキーワードであるが、うっかり main 関数のようなグローバルな関数をそれで囲んでしまうと大変なことになる。マングリングによってラベルが変化し、自分が意図した通りにリンカから見えなくなるからである。

namespace はスコープを変えるんだというごく当たり前のことがことがわかっていればこんなことは多分普通やらないんだと思います。多分。ただ、そういう理屈もわかっていない初心者とか、以下のような多段 namespace のマクロを全ファイルに適用するのが癖になっている人とかは要注意である。

--- test.h ---

#ifndef __TEST_H__

#define __MUMUMU_NAMESPACE_NAME__ mumumu
#define __AHO_NAMESPACE_NAME__ aho

//
// namespace macro
//
#define __HOGE_NAMESPACE_START__ \
namespace __MUMUMU_NAMESPACE_NAME__ { \
namespace __AHO_NAMESPACE_NAME__ {
#define __HOGE_NAMESPACE_END__ } }

#endif // end of __TEST_H__

--- test.cpp ---

#include "test.h"

__HOGE_NAMESPACE_START__

int main(int argc, char *argv[]) {
return 0;
}

__HOGE_NAMESPACE_END__

上記の test.cpp をコンパイルすると、以下のようになる。

$ g++ test.cpp
/usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib/crt1.o: In function `_start':
/build/buildd/glibc-2.9/csu/../sysdeps/i386/elf/start.S:115: undefined reference
to `main'
collect2: ld はステータス 1 で終了しました

test.cpp を コンパイルし、main の text セクションのみをダンプすると以下のようになる。namespace の情報がラベルに付加されていることがわかる。

$ g++ -c test.cpp
$ objdump -x test.o | grep main
00000000 g F .text 0000000a _ZN6mumumu3aho4mainEiPPc

0 件のコメント: