John
John

Reputation: 1032

Using namespaces and includes

The question might be trivial (and possibly a duplicate).

As far as I understand, a C/C++ header file (with a using namespace in it), when used by other source files, it is copied right at the point where the #include directive was in that source file.

Also, given that a source file uses a relatively large number of include directives and that there may be a couple of "redefinitions" for the entire standard library (simply targeted at different implementations).

Here is the main question: How do I know which namespaces am I currently using at any point in the source file if the source file has no using namespace statement?

I'm reading through source files and I have no idea which namespace is being used.

One can override the namespace cleverness by using something like ::std::getline().

If there is no easy way of determining the namespace, is it fair to refactor those files, such that where say string is used to replace it with ::std::string?

Upvotes: 2

Views: 1421

Answers (4)

Christoph Lipka
Christoph Lipka

Reputation: 668

There are three approaches I can think of right now:

Use the IDE: A modern development environment should be able (possibly with the help of plug-ins) to analyze your code while you edit, and tell you the authoritative qualified name of any identifier you hover the mouse cursor over.

Of course this is not an option if you are not using an IDE, and sometimes even IDEs may get confused and give you wrong information.

Use the compiler and guesswork: If you already have a hunch which namespace you might be in, you can define some object, reference it via qualified name, and see if the code compiles, like so:

const int Fnord = 1;
const int* Probe = &::solid::guess::Fnord;

One caveat is that it may give misleading results if using namespace or anonymous namespaces are involved.

Use the preprocessor: Most compilers define a preprocessor macro that tells you the name of the function it is used in, which may include the namespace; for example, on MSVC, __FUNCTION__ will do just this. If the file contains a function that you know will be executed, you can have that function tell you its authoritative qualified name at run-time, like so:

int SomeFunction(void)
{
    printf("%s\n", __FUNCTION__);
}

If you can't use standard output, you might store the value in a variable and use a debugger to inspect it.

If you can find no such function, try defining a class with a static instance of itself, and placing the code in the constructor.

(Unfortunately I can't think of a way to inspect the macro's value at compile-time; static_assert came to my mind, but it can't be used inside functions, and __FUNCTION__ can't be used outside.)

The macro is not standardized though, and may not include the namespace (or it may not exist at all). On GCC for instance, __FUNCTION__ will only give you the unqualified name, and you will have to use __PRETTY_FUNCTION__ instead.

(As of C99 and C++11 there does exist a standardized alternative, __func__, but the format of the function name is unspecified, and may or may not include the namespace. On GCC it does not.)

Upvotes: 1

Aconcagua
Aconcagua

Reputation: 25526

using namespace does not do what you expect...

If you want to place functions, classes or variables in a namespace, you do it this way:

namespace foo
{
    void f();
}
namespace bar
{
    void f();
}

This declares two functions f in namespaces foo and bar respectively. The same you will find in header files; if there is no namespace specified as above, then the function/class/variable is in global namespace. Nothing more.

using namespace now allows you to use functions from a namespace without having to specify it explicitly:

// without:
foo::f();
bar::f();
f();      // unknown!

using namespace foo;
foo::f(); // still fine...
bar::f();
f();      // now you call foo::f

Be aware that this is bad practice, though (the link refers to namespace std, but same applies for all namespaces).

This is even worse in header files: there is no way to undo the effect of a declared using namespace <whatever> again – so you impose it on all users of your header, possibly causing great trouble to some of them. So please don't ever use it in header files.

Upvotes: 1

Pete Becker
Pete Becker

Reputation: 76305

If you don't have a using namespace ... directive you're not using any namespace. In general, your code should refer to things in the standard library with their full names, e.g., std::cout, std::get_line(), std::string.

Yes, you can save your self some typing at the expense of loss of clarity and sometimes mysterious compilation failures or, worse, runtime failures with using namespace std;. After that, you don't have to put std:: in front of the names of things in the standard library: cout, get_line(), string. The using directive puts those names into the global namespace, along with a bunch of sludge that you probably aren't interested in.

If you use something like using namespace std; it should appear only in a source file, never in a header. That way you can tell which namespaces have been "used" by looking at the top of the file. You shouldn't have to track through all your headers for stray using directives.

Upvotes: 4

IceFire
IceFire

Reputation: 4137

using namespace does not mean that you currently use this specific namespace. It means, that all types, variables and functions from this namespace are now in your global namespace, for this translation unit. So, you might have multiple of these statements.

This is why header files should never use using namespace. There is no easier way than using std::string within a header file, you should always be very explicit about the namespace without using namespaces.

Having used using namespace xxx, there is no way of finding out that xxx is now in global namespace, I am afraid.

Upvotes: 1

Related Questions