1

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

using namespace std;

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

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

4

3 回答 3

4

尝试使用objdump来获得带有 & 而没有“使用命名空间 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;

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

于 2013-09-11T12:22:06.673 回答
4

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

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

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

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

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

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

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

于 2013-09-11T12:45:42.847 回答
0

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

于 2018-12-07T21:23:11.233 回答