2

I have a C++ code that uses endl, vector, complex, and cout occasionally without any namespace qualification. When compiling with GCC 4.9, I get errors like this one:

bfm.h:454:4: error: 'complex' does not name a type
    complex<double> inner(Fermion_t x,Fermion_t y);
    ^

In the very same file, there are lines with an std:: qualifier:

std::complex<Float>   dot(Fermion_t x_t, Fermion_t y_t,int sx,int sy);

Throughout the codebase, I saw the following template specializations used

  • std::complex<double>
  • std::complex<cFloat>
  • complex<Float>
  • complex<double>
  • complex<T>
  • complex<S>.

Neither for the regular express struct\s+complex nor class\s+complex I managed to find something in the codebase or the codebase of the base library. Therefore I assume that it indeed is the standard library complex type.

There are a couple of using namespace std scattered around in various header files, but not all of them.

I tried compiling this codebase with GCC 4.9 and Clang 3.7. Both give similar errors about the missing type. Is there some possibility that this has worked with an older version of GCC? I have tried to insert std:: at all the needed points but I have the impression that I do something wrong if I cannot just compile the source checkout that is meant for this type of computer.

Martin Ueding
  • 8,245
  • 6
  • 46
  • 92
  • 4
    "There are a couple of `using namespace std` scattered around in various *header* files" good luck. – Guillaume Racicot Nov 24 '16 at 15:02
  • 2
    Implicit `using namespace std` is a *bad* idea. As is [using it in header files](http://stackoverflow.com/questions/5849457/using-namespace-in-c-headers) (or in general). – Some programmer dude Nov 24 '16 at 15:08
  • Create a new header file say "configuration.h" and write only one statement in it "using namespace std;" and include this header file in all implementation files(i.e all. cpp files) – Khurram Shehzad Nov 24 '16 at 15:09
  • Other compilation errors that I have is that pointers (on a 64-Bit IBM Power A2) are casted into `unsigned int`, compilers complain that this loses information. Then there is `1< – Martin Ueding Nov 24 '16 at 15:10
  • 5
    I would remove all of the `using namespace std;` from the header files and start from there. – Galik Nov 24 '16 at 15:11
  • @Someprogrammerdude: I know that this line causes problems, especially in headers. Your wordings sounds like you know how this `using namespace std` line can be injected implicitly? – Martin Ueding Nov 24 '16 at 15:17
  • 2
    No I'm not saying it can be done. All I'm saying is that it's a bad idea. Allow me to rephrase it: ***If*** it was possible, implicit `using namespace std` would be a *really* bad idea. – Some programmer dude Nov 24 '16 at 15:19
  • @KhurramShehzad, @Galik: There are more matches for `std::complex<` than `[^:]complex<`, so I think removing all the `using namespace` would actually be less work and give the better result. – Martin Ueding Nov 24 '16 at 15:22
  • 2
    @KhurramShehzad That's a great way to get into a lot of trouble with totally innocent names like `sort` or `transform`. `using namespace std;` should be *avoided,* not *encouraged!* – Angew is no longer proud of SO Nov 24 '16 at 16:05
  • @Angew: After a few days were wasted at compiling a C program with C++ because there was a `struct operator` in it, one should not make life harder than it is and introduce `using namespace std` into a legacy codebase. I totally agree. I have removed all `using namespace std` and added `std::` in front of everything. Now I got errors like `enum E {...}; E e; e = atoi(...);` which I have to figure out. I have worked around the issue presented in this question, I still would like to understand how the original author was able to compile his code. – Martin Ueding Nov 24 '16 at 16:12
  • In order to compile without modifying the code itself, maybe you can use the command line option `-include` and the @KhurramShehzad idea. See [Preprocessor options](https://gcc.gnu.org/onlinedocs/gcc-2.95.2/gcc_2.html#SEC11) – Wilfredo Pomier Nov 24 '16 at 21:29
  • @WPomier: Thanks for the tip, I might need that. I have checked this code into git now and change it. After I ran it though `clang-format`, any hopes of merging it are gone, anyway. So now I just edit the code and try to compile it. – Martin Ueding Nov 24 '16 at 21:31

1 Answers1

1

you can use selective using... declarations or type aliasing to bring in only the std:: members you need. Like:

using std::complex; 
using std::cout;
using std::endl;

cout << "Hello world" << endl; // works
complex<float> x; // works

fstream y; // compile error, no namespace qualification, no using declaration
std::fstream z; // OK

Ah, yes, maybe not that evident, so perhaps worth mentioning. You now that std::endl? Well, it's a stream manipulator, a function in fact. Which means one can bring in the current block function members from other namespaces as well.

Like:

#include <cmath>
#include <cstdlib>
inline void dummy(float x) {
  float y=fabs(x); // Na'a.., fabs is imported into std namespace by <cmath>

  using std::itoa; // same is itoa, but we'll be using it
  char buff[128];
  itoa(42, buff, 10); // OK
}
Adrian Colomitchi
  • 3,974
  • 1
  • 14
  • 23