1

I have a complicated least-squares fitting program, which I was recently debugging. I was debugging stuff by cout-ing them to the console, and to make it easier, I used

using namespace std;

and funnily, after weeks of coding, I wanted to remove this because debugging is done, and the surprise was that removing it causes the result to be wrong! I did a complete abstract check in g++ and icpc (intel compiler) where I remove and restore this directive, and when it's removed, the result it wrong...

I know it's a very broad question and not easy to hit the answer, but what would you do in this case? How would you debug such a dependence?

The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189
  • 2
    Calling anything in `` unqualified? – Jesse Good Sep 11 '13 at 12:02
  • Is `using namespace std` the only thing you removed? – juanchopanza Sep 11 '13 at 12:04
  • Could you share actual error (or) simplified code to produce this issue? – Arunprasad Rajkumar Sep 11 '13 at 12:05
  • Well done, removing `using namespace std` is the first step to gain a good C++ code style – Manu343726 Sep 11 '13 at 12:05
  • 2
    Check the names you defined yourself against a list of library names (can be found in C++ standard drafts) to see where you got a clash. This could happen if the `using` directive pulled an overload of some function from `std` that is a better match than one of yours. And next time, use `using std::cout;` instead, mkay? :) – jrok Sep 11 '13 at 12:06
  • @JesseGood I'm not sure. The problem is that the program is huge. I'm trying to check that, but there's no systematic way I know of that I could try. – The Quantum Physicist Sep 11 '13 at 12:08
  • @juanchopanza yes, it's the only thing I remove. – The Quantum Physicist Sep 11 '13 at 12:08
  • @Arun unfortunately not. The program is huge and the problem is unusual. So I'm not sure how to make it abstract, that's why I'm asking for ideas for systematic checking of the problem. – The Quantum Physicist Sep 11 '13 at 12:09
  • @SamerAfach Can you try including #include ..? What is the target platform ..? – Arunprasad Rajkumar Sep 11 '13 at 12:12
  • What *jrok* said (*This could happen if the using directive pulled an overload of some function from std that is a better match than one of yours.*) is the most plausible reason of such behaviour. – SChepurin Sep 11 '13 at 12:14
  • @SamerAfach Also you can try to compare the object file variations using objdump(compare the o/p of objdump with and without using namespace std) – Arunprasad Rajkumar Sep 11 '13 at 12:15
  • @Arun Adding math.h didn't fix it. I'm using g++/icpc on linux ubuntu. – The Quantum Physicist Sep 11 '13 at 12:15
  • @Arun I'm sorry, I don't know what objdump is. Can you please provide a reference? – The Quantum Physicist Sep 11 '13 at 12:16
  • @SamerAfach objdump executable-without-using-std -d > no-std; objdump executable-with-std -d>with-std; diff -urN no-std with-std; If you see any difference function call instruction that is the culprit. – Arunprasad Rajkumar Sep 11 '13 at 12:17
  • You could try to add the using directive to each source file instead of adding it to a common header (I'm guessing that's what you did). Then remove it one by one and checking if each removal breaks things. This way you could restrict the scope of the search (I hope). If the using directive is needed also for some code in the headers, try to move it inside blocks (i.e. remove it from global scope), so that to remove dependencies before you start the step-by-step removal. Compile and test after each single change, so as to track down the issue. – LorenzoDonati4Ukraine-OnStrike Sep 11 '13 at 12:24
  • 1
    @SamerAfach "The problem is that the program is huge": but your unit tests should be able to pinpoint the functions whose behaviour has changed. You do have unit tests, don't you? – Mike Seymour Sep 11 '13 at 12:56

3 Answers3

4

Try objdump to get the difference of executable with & without "using namespace std;"

Use objdump -d [executable | objfile] to disassemble the ELF.

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

If you see any difference function call instructions, then that should be the problematic one.

Arunprasad Rajkumar
  • 1,374
  • 1
  • 15
  • 31
4

This is why using-directives in the global namespace (or any other inappropriately wide scope) are a bad idea. It's not just a matter of style; it can change the meaning of the code in subtle ways. See this question for a thorough discussion of the issues.

Almost certainly, your code uses names from the standard library without qualification, and those names are also declared in the global namespace. Thus, removing using namespace std; changes the meaning of those unqualified names, rather than just making the code fail to compile.

These might be names from your code; or perhaps they are C library functions. Many (particularly those in <cmath>) are overloaded for various types, where the C library itself only declares a single function. It's unspecified whether none, some, or all of these are dumped into the global namespace as well as namespace std.

For example, you might have a function call

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

With using namespace std;, this will select the overloaded float std::sin(float) that you've dumped into the global namespace. Without it, depending on what the implementation chooses to do with the global namespace, it might still call that; or it might call double sin(float) from the C library; or it might fail to compile.

In the case of GCC, it seems that the C library function, but not the C++ overloads, are dumped into the global namespace, as I discovered while answering this question.

Community
  • 1
  • 1
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

Math functions usually cause these kind of issues. I was having problems with abs(), which switched to C-Style as soon as I removed the "using" directive.