【问题标题】:Legacy c++ code does not contain std:: prefix遗留 c++ 代码不包含 std:: 前缀
【发布时间】:2017-12-22 14:45:19
【问题描述】:

我正在使用 g++ 4.4.7 编译一段非常古老的遗留代码。我对这段代码真正了解的是,它是在 Irix/Sun 系统上开发的,这意味着它具有 MIPS 架构。我在使用此代码时发现的一件相当奇怪的事情是,它有时会调用像 endlset_new_handler 这样的函数,而没有 std:: 前缀。显然这会导致编译错误。由于我假设这段代码有时会在某些机器上编译,因此我对盲目添加 std:: 前缀以使其编译有点谨慎,因为它可能会改变行为。

那么,是否有一些旧的非 ISO 编译器允许编译这段代码?或者是否有某种标志可以传递给 gcc 以允许这段代码工作?

【问题讨论】:

  • 我猜是 Turbo-C++,它没有实现命名空间。另外,祝你好运:|
  • 我明白了。我的错,我纠正了。提醒自己:回答前喝两杯咖啡
  • 我的公司在 Solaris 上使用 gcc。无论如何,“软件腐烂”的说法适用于这种情况。由于平台或语言发展等原因,未维护的旧代码“腐烂”。通常,在过去几十年中发展的唯一语言是正在使用的语言......而 C++ 在这一指标上取得了非凡的成功。
  • @roscoe • 我经常遇到这种问题。问题是“这个 C++ 源代码来自大约 1990 年,我需要让它使用 C++17 进行编译”。我采取的方法是卷起袖子,将代码重构为现代 C++。 (代码在踢和尖叫,而我在哭泣和抽泣。)没有简单的解决方法。而且我认为让一个旧的编译器来编译旧的源代码是作弊,并且可能不可行。

标签: c++ gcc g++ iso legacy-code


【解决方案1】:

std 命名空间直到 1998 年的第一个 ISO/IEC 标准(通常称为 C++98)才被引入 C++。在此之前,所有标准库函数和对象都是全局命名空间的一部分。

Herb Sutter 在 2000 年写了一篇名为 Migrating to Namespaces 的文章,详细介绍了他对过渡的建议。

我不知道有任何编译器标志会将 std 命名空间折叠到全局命名空间中,无论如何这将是一个坏主意 - std 现在比以前大得多首次引入,名称冲突几乎是肯定的。见Why is “using namespace std” considered bad practice?

您不太可能与 1998 年之前的标准库中的名称发生冲突,因此将这些名称单独拉入全局命名空间应该是安全的。如果您使用的是预编译头文件,则可以在包含定义符号的标准头文件并静默修复整个项目后将using 指令放入其中。只需为您遇到的每个编译器错误添加一行。

using std::endl;
using std::set_new_handler;

如果您的目标是在尽可能少的时间和精力下让代码启动并运行,我只会建议您这样做。更好的长期解决方案仍然是将std:: 放在库中所有名称的前面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-18
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 2020-04-12
    • 1970-01-01
    相关资源
    最近更新 更多