【问题标题】:std::bind compiler error gccstd::bind 编译器错误 gcc
【发布时间】:2016-11-13 08:49:52
【问题描述】:

在我最近的一个项目中,我在 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 本身有关?

【问题讨论】:

  • std::bind 函数在<functional> 标准头文件中声明。仅仅因为您足够幸运,其他一些头文件恰好包含它并不意味着什么。如果你想使用std::bind,你应该明确地包含<functional>
  • 你没有在问题中回答你自己的问题吗?我很困惑。

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


【解决方案1】:

无法保证所有 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++ 标准的扩展或小偏差,从而被绑定到特定的编译器版本。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 但是如果不包括<functional>,它怎么可能工作呢?
    • @cplusplusrat 您包含的另一个标头在内部使用<functional>,或者至少是其中定义std::bind 的部分。
    【解决方案3】:

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

    不,你不能。您的版本可能存在允许编译一段不合格代码的错误,而更高版本可能已修复该错误,这会导致该违规代码出现编译器错误。

    事实上,这基本上就是发生在你身上的事情。它本身并不是一个真正的错误,但您使用了标准头文件中的函数并且您从未包含该头文件。 std::bind 住在 <functional>。它在不包含<functional> 的情况下编译的事实是非标准行为。当您移至一个未在其中一个标头中包含 <functional> 的编译器时,您确实包含它破坏了编译。

    还是我过于乐观,应该依赖更多的测试?

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

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

    这与std::bind 无关,而是与您编写代码的一致性有关。在需要时不包括 <functional> 会使您的代码不符合要求。

    【讨论】:

    • 是的,所有合理的建议和时间允许,我会进行更严格的代码审查。叹息……这就是生活。生活和学习...
    • @cplusplusrat 是的。通常,我们从失败中学到的最多。
    • 猜猜,对我来说一个相关的问题是这个。怎么知道代码是否严格遵循 C++ 11 标准。通过代码审查强制执行 C++ 11 标准对于任何重要的项目都不是可行的解决方案。所以我对此的自然回答是测试。但是有多少不同的编译器和版本呢?猜猜我要问的是,如果不能选择阅读整个代码库,你会做多少测试来确保你的代码严格遵循 C++11 标准?
    • 为了提供更多上下文,gcc 5.3 将很高兴地编译 std::bind<memory> 而不需要上述 <functional>
    猜你喜欢
    • 2013-09-01
    • 2017-06-27
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    相关资源
    最近更新 更多