为什么这行得通?
我看到类似的 SO 问题说明它确实如此,但有人可以更详细地解释它吗?特别是,这种行为是否受标准保护?
我
#ifndef I_H_
#define I_H_
typedef void (*FuncPtr)();
template<typename T>
void FuncTemplate() {}
class C {};
#endif
cc
#include "i.h"
FuncPtr a() {
return &FuncTemplate<C>;
}
b.cc
#include "i.h"
FuncPtr b() {
return &FuncTemplate<C>;
}
mcc
#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
中实例化一次,因此地址应该每个指向一个副本。毕竟这些结果如何相同,这种行为是可移植的还是受保护的?a.o
b.o
编辑共享库案例:
$ 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