phs*_*phs 7 c++ linker templates function c++-address
为什么这样做?
我看到类似的SO问题说它确实如此,但有人可以更详细地解释它吗?特别是,这种行为是否受到标准的保护?
IH
#ifndef I_H_
#define I_H_
typedef void (*FuncPtr)();
template<typename T>
void FuncTemplate() {}
class C {};
#endif
Run Code Online (Sandbox Code Playgroud)
a.cc
#include "i.h"
FuncPtr a() {
return &FuncTemplate<C>;
}
Run Code Online (Sandbox Code Playgroud)
b.cc
#include "i.h"
FuncPtr b() {
return &FuncTemplate<C>;
}
Run Code Online (Sandbox Code Playgroud)
m.cc
#include <iostream>
#include "i.h"
FuncPtr a();
FuncPtr b();
int main() {
std::cout << (a() == b() ? "equal" : "not equal") << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后
$ 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
Run Code Online (Sandbox Code Playgroud)
抛到-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
Run Code Online (Sandbox Code Playgroud)
这包含在一个定义规则中:
类类型(第9条),枚举类型(7.2),带内部链接的内联函数(7.1.2),类模板(第14条),非静态函数模板(14.5.6)可以有多个定义,类模板的静态数据成员(14.5.1.3),类模板的成员函数(14.5.1.1),或者在程序中未指定某些模板参数(14.7,14.5.5)的模板特化,前提是每个模板定义出现在不同的翻译单元中,并且定义满足以下要求.鉴于这样一个名为D的实体在多个翻译单元中定义,那么
随后必须遵守的标准列表或其未定义的行为.在上面这些确实成立.然后 ...
如果D的定义满足所有这些要求,那么程序应该表现得就像D的单一定义一样.
因此,从技术上讲,您可以在每个翻译单元中获得该功能的副本.
看起来在最后一个短语中的措辞使得它们都要求它们都表现相同.这意味着获取任何这些对象的地址应该产生相同的地址.