なぜこれが機能するのですか?
同様のSOの質問が表示されますが、誰かがそれをより詳細に説明できますか? 特に、この動作は標準によって保護されていますか?
ああ
#ifndef I_H_
#define I_H_
typedef void (*FuncPtr)();
template<typename T>
void FuncTemplate() {}
class C {};
#endif
a.cc
#include "i.h"
FuncPtr a() {
return &FuncTemplate<C>;
}
b.cc
#include "i.h"
FuncPtr b() {
return &FuncTemplate<C>;
}
m.cc
#include <iostream>
#include "i.h"
FuncPtr a();
FuncPtr b();
int main() {
std::cout << (a() == b() ? "equal" : "not equal") << std::endl;
return 0;
}
それで
$ g++ -c -o a.o a.cc
$ g++ -c -o b.o b.cc
$ g++ -c -o m.o m.cc
$ g++ a.o b.o m.o -o prog
$ ./prog
equal
-Wall -Wextra -Werror -ansi
すべてのg++
呼び出しに投げると、同じ結果が得られます。
私の(単純な)理解では、とFuncTemplate
の各コンパイル単位で 1 回インスタンス化されるため、アドレスはそれぞれ 1 つのコピーを指す必要があります。結局のところ、これらはどのようにして同じになるのでしょうか? また、この動作は移植可能または保護されていますか?a.o
b.o
EDIT共有ライブラリのケース:
$ g++ -shared -o liba.so a.cc
$ g++ -shared -o libb.so b.cc
$ g++ -c -o m.o m.cc
$ g++ -L. -la -lb m.o -o prog
$ ./prog
equal