"Using Namespace" in C++ Headers

using namespace in c++ headers [duplicate]

You should definitely NOT use using namespace in headers for precisely the reason you say, that it can unexpectedly change the meaning of code in any other files that include that header. There's no way to undo a using namespace which is another reason it's so dangerous. I typically just use grep or the like to make sure that using namespace isn't being called out in headers rather than trying anything more complicated. Probably static code checkers flag this too.

The header should include just the headers that it needs to compile. An easy way to enforce this is to always include each source file's own header as the first thing, before any other headers. Then the source file will fail to compile if the header isn't self-contained. In some cases, for example referring to implementation-detail classes within a library, you can use forward declarations instead of #include because you have full control over the definition of such forward declared class.

I'm not sure I would call it common, but it definitely shows up once in a while, usually written by new programmers that aren't aware of the negative consequences. Typically just a little education about the risks takes care of any issues since it's relatively simple to fix.

C++ headers and namespaces

You seem to be conflating two distinct concepts. A header is a file, typically used to contain declarations. It can contain function declarations, classes, templates, etc.

A namespace is a means of defining a scope, within which all items declared are unique. This allows you to use function and class names that might otherwise clash with names in the standard. For example

namespace mystuff
{
class list { };
};

Your list will not conflict with std::list.

Namespaces can and should be used in header files to declare the classes and such that are part of that namespace. However, as noted by others, using a 'using' directive in a header file is discouraged because it can create the very name conflicts the namespace was intended to solve.

C++: Namespaces -- How to use in header and source files correctly?

From a code readability standpoint, it is probably better in my opinion to use the #2 method for this reason:

You can be using multiple namespaces at a time, and any object or function written below that line can belong to any of those namespaces (barring naming conflicts). Wrapping the whole file in a namespace block is more explicit, and allows you to declare new functions and variables that belong to that namespace within the .cpp file as well

Why is including using namespace into a header file a bad idea in C++?

Consider this program:

line#
1 #include <string>
2
3 using namespace std;
4
5 struct string { const char* p; }; // Beware: another string!
6
7 int main()
8 {
9 string x; // Error: ambiguous - which string is wanted?
10 }

If you try to compile it, you'll see errors:

g++     using.cc   -o using
using.cc: In function `int main()':
using.cc:9: error: use of `string' is ambiguous
using.cc:5: error: first declared as `struct string' here
/usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stringfwd.h:60: error:
also declared as `typedef struct std::basic_string<char, std::char_traits<char>, std::allocator<char> > std::string' here
using.cc:9: error: `string' was not declared in this scope
using.cc:9: error: expected `;' before "x"

The problem here is that when main() specifies string x;, the compiler's not sure whether the user-defined ::string or included std::string is wanted.

Now imagine you take the top part of the program... lines 1 through 5 - up to and including the struct string... and put it into a header file which you then #include before main(). Nothing changes: you still have an error. So, just as for standalone programs, header files with using statements in them can cause trouble for other code that includes them, making some of their statements ambiguous.

It can be a bigger pain though, as headers can be included - directly or indirectly - by arbitrarily huge amounts of dependent code, and...

  • removing the using statement from the header, or
  • a change to the contents of <string>, or any other header affecting std::

...might break code including the problematic header. Either problem may render dependent code uncompilable, and issues may not even be noticed until another compilation is attempted. Further, the person suffering due to the using statement may not have filesystem/code-repository permissions, corporate authority etc. to remove the using statement from the header, nor fix other affected client code.

That said, if a header only has "using" inside a class or function, then there's no affect on code beyond that scope, so the potential impact of changes to std:: is dramatically reduced.

Is it ok to have using namespace statement in a header file? [duplicate]

Because header files get included by other files, you pollute the global namespace of other people who use your code. You may think a little pollution is okay, but if everybody thought that way, we would run out of good names quickly. If you really can't resist using namespace directives in your headers, then limit it to within your header. You can do that by putting the directive inside a scope. For example, if you have your own namespace block, the body of which is entirely restricted to your header file, then you can put a using directive in it without polluting the global namespace.

namespace your_namespace
{
// this directive is restricted to this namespace block
using namespace ALongNameSpaceName::LongerNamespaceName;

...
}

You can do this inside functions too without worrying about it affecting other code.

Can I include a headerfile in a namespace?

System header files like <conio.h> which are intended to be used in both C and C++ will enclose their declarations in an extern C scope, forcing C linkage for all that is contained in them, regardless of whatever additional C++ namespaces you add. That’s why your code compiles in this case.

See also this, which is almost a duplicate of this question, but not exactly.

In short, yes it’s valid, but I would strongly encourage against it. There are many other ways to solve this problem, like creating wrapper modules for the functions you want to have alternate symbols for.

As a side note: try putting your own getch in an extern C block. My guess is you’ll get a linker error.

Including C headers in a C++ namespace - is it a standard behavior?

You may even do strange things like

//test.c
int
#include "main.h"
{
return 1;
}

//main.h
main(void)

The preprocessor macros are expanded before any syntax check is done. The above example will expand to

int
main(void)
{
return 1;
}

which is legal code. While you really should avoid such examples, there are cases, where including into another element is quite useful. In your question it depends on how the names are mangled during compilation. If all the definitions in your header file are declared with extern "C", the names will be searched unmangled in the object file, this is, however, not the case if the object file containing the implementation does not use the same namespace as it's definition in the consuming code and does not declare it extern "C".

When using C headers in C++, should we use functions from std:: or the global namespace?

From the C++11 Standard (emphasis mine):

D.5 C standard library headers [depr.c.headers]

  1. For compatibility with the C standard library ...
  2. Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard
    library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).
  3. Example: The header <cstdlib> assuredly provides its declarations and definitions within the namespace
    std
    . It may also provide these names within the global namespace. The header <stdlib.h> assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It
    may also provide these names within the namespace std.

Using the «name.h» headers is deprecated, they have been identified as candidates for removal from future revisions.

So, I would suggest to include the «cname» headers and to use the declarations and definitions from the std namespace.

If you have to use the «name.h» headers for some reasons (it's deprecated, see above), I would suggest to use the declarations and definitions from the global namespace.

In other words: prefer

#include <cstdio>

int main() {
std::printf("Hello world\n");
}

over

#include <stdio.h>

int main() {
printf("Hello world\n");
}


Related Topics



Leave a reply



Submit