【问题标题】:Removing using namespace std causes the program to get crap results删除 using namespace std 会导致程序得到垃圾结果
【发布时间】:2013-09-15 10:40:11
【问题描述】:

我有一个复杂的最小二乘拟合程序,我最近正在调试它。我通过将它们 cout 到控制台来调试东西,为了使它更容易,我使用了

using namespace std;

有趣的是,经过数周的编码,我想删除它,因为调试已经完成,令人惊讶的是,删除它会导致结果错误!我在 g++ 和 icpc(intel 编译器)中做了一个完整的抽象检查,我删除并恢复了这个指令,当它被删除时,结果是错误的......

我知道这是一个非常广泛的问题,不容易找到答案,但在这种情况下你会怎么做?您将如何调试这种依赖关系?

【问题讨论】:

  • <cmath>中调用任何内容不合格?
  • 只有using namespace std 是你删除的吗?
  • 您能否分享实际错误(或)简化代码来产生此问题?
  • 对照库名称列表(可以在 C++ 标准草案中找到)检查您自己定义的名称,看看哪里有冲突。如果using 指令从std 中提取了某些函数的重载,则可能会发生这种情况,这比你的一个更好的匹配。下一次,改用using std::cout;,好吗? :)
  • @SamerAfach “问题是程序很大”:但是您的单元测试应该能够查明行为发生变化的函数。你确实有单元测试,不是吗?

标签: c++ debugging error-handling g++ std


【解决方案1】:

这就是为什么在全局命名空间(或任何其他不适当的范围)中使用指令是一个坏主意的原因。这不仅仅是风格问题。它可以以微妙的方式改变代码的含义。有关这些问题的详细讨论,请参阅 this question

几乎可以肯定,您的代码不加限定地使用标准库中的名称,并且这些名称也在全局命名空间中声明。因此,删除using namespace std; 会改变那些非限定名称的含义,而不仅仅是使代码无法编译。

这些可能是您代码中的名称;或者它们可能是 C 库函数。许多(尤其是<cmath> 中的那些)针对各种类型进行了重载,其中C 库本身只声明了一个函数。未指定是否将这些、部分或全部转储到全局命名空间以及namespace std

例如,你可能有一个函数调用

float angle = whatever;
float sine = sin(angle);

使用using namespace std;,这将选择您已转储到全局命名空间中的重载float std::sin(float)。没有它,取决于实现选择对全局命名空间做什么,它可能仍然会调用它;或者它可能会从 C 库中调用 double sin(float);否则可能无法编译。

在 GCC 的情况下,似乎 C 库函数,但 不是 C++ 重载,被转储到全局命名空间中,正如我在回答 this question 时发现的那样。

【讨论】:

  • 问题出在 abs() 上。谢谢。
  • @SamerAfach:是的,abs() 会导致比我提到的<cmath> 函数更大的浮点值问题,因为 C 库函数将转换为 int
【解决方案2】:

尝试 objdump 以获取带有 & 不使用“using namespace std;”的可执行文件的区别

使用objdump -d [可执行| objfile] 来反汇编 ELF。

objdump executable-without-using-std -d > no-std;
objdump executable-with-std -d > with-std;
diff -urN no-std with-std;

如果您看到任何不同的函数调用指令,那么这应该是有问题的。

【讨论】:

  • 我的程序除了可执行调用之外还需要参数。我可以向 objdump 调用添加参数吗?
  • 你不需要,objdump不会执行程序。
  • @SamerAfach objdump 将反汇编给定的 ELF(可执行文件或目标文件)。它永远不会执行,所以不用担心命令行参数。
  • 我正在经历这个......有太多不同之处。我正在关注他们,看看是否有任何意义。
  • @SamerAfach 如果您确定特定的源文件,那么只需检查该目标文件反汇编而不是整个可执行文件的差异。 (注意:如果您看到任何 C++ 损坏的名称差异,请使用 c++filt 对其进行解码)
【解决方案3】:

数学函数通常会导致这类问题。我在使用 abs() 时遇到问题,一旦我删除了“using”指令,它就会切换到 C 样式。

【讨论】:

    猜你喜欢
    • 2011-10-14
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 2021-11-23
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多