关于#pragma interface

关于这个pragma,有某文档: http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Interface.html 里面还有它的伴生pragma: #pragma implementation

大体意思是说,比如你有个A.h,有个A.cpp。A.h里面包含了一些除了类接口以外的一些东西,例如一部分类实现之类的,比方说,里面有类A,以及A::foo()的实现。

原来假如我是B.cpp,只要我#include你这个A.h,那我编译出来的B.o里面,就会有你的那一部分实现的副本,也就会有A::foo()的副本……

然后有人觉得这样B.o会变大,于是发明了那俩pragma……

定义了#pragma interface A 的头文件,引用它的B.cpp编译出来的B.o就不会包含那一部分实现的副本,而会有undefined symbol: undefined A::foo()

而与其对应的定义了#pragma implementation A的A.cpp,它编译出来的A.o里面,就会包含那一部分实现,也就是那些undefined symbol对应的东西: defined A::foo()

这样俩.o链接起来,就啥都有了,很好

=== bug的分隔线 ===

但是有时候有别的情况…… 例如其实那个类在一个C.so里面,而引用它的B.cpp是一个用了那个C.so的程序的一部分

于是B.cpp编译出来的B.o里面,那部分实现依旧是undefined symbol。但是,那些对应的symbol,在A.o和其他.o一起变成C.so的时候,都到了C.so里面。但是大概是由于链接的过程,原来的symbol信息没有导出来……

于是C.so的导出symbol里面,并没有defined A::foo()

于是B.cpp位于的那个程序在链接的时候,就找不到那个A::foo()了,就有linker error了……

=== 结论的分割线 ===

总的来说,就是尽可能别用这个pragma…… 省那点空间没啥意义的……

它文档里也说了

Note: As of GCC 2.7.2, these #pragmas are not useful in most cases

以及

Currently (3.4) the only benefit of these #pragmas is reduced duplication of debugging information, and that should be addressed soon on DWARF 2 targets with the use of COMDAT groups.