GCC 与 MSVC 中的成员函数模板特化

/ 0评 / 0

项目中的一部分实现要求高性能并且稳定,于是准备使用代码分离,高性能和可用性的部分用 C++ 完成,然后编译成 Python 模块,与业务层实现对接。

我在这里使用了 Boost::Python 来进行 C++ 代码的导出。

由于自己在 C++ 方面算是个新手,尤其是在对编译器的工作方面理解的不够深刻,于是在 Linux 中决定自己手动进行编译、链接的工作。果然,第一次编译就喜提了一大堆的 error 与 warning... 我在 MSVC 中赶紧把编译器警告级别提高到了 W4,根据相关的提示信息进行了修改,现在还剩下一个让我十分不解的问题:

上面的这一段代码是用来在字节流中格式化出指定的变量,特化的模板函数用于针对 std::string 类型给出结果,在 Windows 平台它工作的很好,编译器没有给出 warning,但当我试图在 gcc 中编译时,却给出了这样的错误:

GCC error: explicit specialization in non-namespace scope

在阅读了上述的解答之后,我知道了,特化的模板函数在 gcc 中是不能直接在类的声明中给出的,需要在类外实现。

经过一番 Debug 之后成功的在 GCC 中编译、链接通过了。

可是在使用 Python 调用时,却出现了 Memory Error

因为工程不算小,我经过了蛮久才定位出了出错的位置:所有调用了这个特化的模板函数的操作都会引起 Memory Error ,而这段代码应该是没什么问题的,因为在 Windows 平台的工作一切正常。

可这又是为什么呢?

模板函数在编译之后和普通函数一样,存在于整个程序的代码区,这部分也是有地址的,代码在调用时其实是调用了函数的地址(指针),将参数入栈进行函数的调用,这部分如果有问题是在编译期间就能发现的;而 Python 这里的 Memory Error 除了内存的 malloc 错误应该就是只对应的函数地址不存在相应的代码。

针对这一点,我便有了一个想法:如果我将函数声明为 inline,在对应的调用地方就会将这段代码进行展开,于是便可能消除这个错误。

我是幸运的,当我将这个成员模板函数声明为 inline 之后,Python 中的调用便成功了。

所以建议大家,如果在 GCC 编译之后,成员模板函数的特化出现了各种奇怪的问题,不妨尝试将函数声明为 inline 来进行 debug;如果函数体较大,可以在 debug 之后删除 inline 标志。

知识共享许可协议
本作品采用知识共享署名 4.0 国际许可协议进行许可。

发表评论

电子邮件地址不会被公开。 必填项已用*标注