std :: bind编译器错误gcc

时间:2016-07-11 11:58:55

标签: c++ linux c++11 gcc

在我最近的一个项目中,我在Ubuntu(cmake + gcc 4.8.4)上进行了开发工作。代码构建正常。但是,当我尝试在cygwin(cmake + gcc 5.3)中构建相同的代码时,我得到了std :: bind的编译器错误。执行#include <functional>时就会消失。但是,这让我有点担心。我希望我的代码能够在相同或非常相似的编译器上正常工作。

我刚刚发布了一段将在CentOS上使用的代码。我只是假设因为我的代码与Ubuntu构建良好,其他具有类似编译器的Linux发行版应该不是问题。但是,我不再确定我的代码是否可以在CentOS上构建好。

我的问题是这个。我可以假设,如果我的代码在我的Ubuntu机器上使用特定版本的gcc构建得很好,它也可以在其他具有相同或更高版本gcc的其他Linux发行版上构建好吗?或者我是否过于乐观并应该依赖更多测试?或者这与std :: bind本身有关吗?

3 个答案:

答案 0 :(得分:3)

无法保证所有gcc编译器版本的行为都相同。特别是w.r.t. C ++ 11的特性在编译器版本之间存在一些不兼容的变化。 gcc 4.8仍然只有实验性的C ++ 11支持。标准说std :: bind附带<functional>,所以gcc 5.3正确地要求你包含它: http://en.cppreference.com/w/cpp/utility/functional/bind

旧版本的gcc可能包含<functional>在其他一些包含的内容中,或者该绑定在另一个包含中提供。

在不同的编译器版本上测试软件总是一个好主意,甚至使用完全不同的编译器(如clang)。否则,您可能会在不知情的情况下使用C ++标准的扩展或小偏差,从而与特定的编译器版本绑定。

答案 1 :(得分:2)

如果您在使用<functional>之前忘记包含std::bind,则您的代码不符合标准,并且无法保证可以在任何地方使用。它对你的特定工具链起作用是不幸的。

答案 2 :(得分:2)

  

我的问题是这个。我可以假设,如果我的代码在我的Ubuntu机器上使用特定版本的gcc构建正常,它也可以在其他具有相同或更高版本gcc的其他Linux发行版上构建好吗?

不,你不能。您的版本可能有一个错误,允许编译一段不符合规范的代码,而后一版本可以修复,这将导致该违规代码的编译错误。

实际上这基本上就是你发生的事情。它本身并不是一个真正的bug,但你使用了标准头文件中的一个函数而你从未包含过该头文件。 std::bind生活在<functional>。在没有包含<functional>的情况下编译它的事实是非标准行为。当您转移到其中一个标题中没有包含<functional>的编译器时,您确实包含它会破坏编译。

  

或者我过于乐观并且应该依赖更多的测试?

是的,如果您尝试发布真正可移植的代码,您应该在多个编译器和系统上测试代码。您最好的防御是严格编写100%标准符合规范。

  

或者这与std :: bind本身有什么关系?

这与std::bind无关,但与你如何使你的代码一致。在需要时不包括<functional>会使您的代码不符合规定。