I read that using directive is not encouraged in C++ saying never put using directives in header files. Why is it like that? Any hint for me?
Thanks!
using namespace x; is a very bad idea, since you have no idea what names you are importing, even with the standard library.
However: using std::cout; and similar statements are a very good idea, because they import symbols explicitly, and make code more readable (though it still might not be a good idea to put them in the global scope in header files).
If you are talking about the 'using' directive, the reason for not using it is because if you say
using namespace std;
in a header file, all files that #include that header will be forced to use that namespace, and that could cause problems.
Because it can break working code, when trying to add your header, if your header namespace trample other namespace that defined in the past-working code.
It is similar to no to declare static variables in header files. Adding using statement in header files will bring the namespace into .cpp files that include the header file. It is not necessary. In the worse case, you may have to change some variable or functions names in .cpp in order to avoid naming conflicts.
Related
I have a class that I need to convert to a template class. For this, I am moving the implementation from class.cpp to class-in.h that will then be included at the end of class.h.
The implementation has a few using ... directives as well as a gflag DEFINE_bool. I need to use these in the class-inl.h file but I am told that they shouldn't be placed in a header file.
The class-inl.h is a header file but it will never be included as a regular header file.
Is there a way I can get rid of using/ gflag in the header file? Can I put the gflag, using statements in a class.cpp?
edit: I meant using declaration example using std::cout
My recommendation is to not put usings into header files if they are only used for implementation. They unnecessarily leak symbols and implementation details. If you define using my_shortcut_for_long_type=...., someone is bound to start using it and code breaks when you decide to change it.
It won't kill you to write std::cout instead of cout. If you want to shorten a long type, place the using into e.g. impl namespace; same goes for what used to be static functions in .cpps. Do not forget to mark them inline if you decide to define them also in the header. using can also be defined inside function scope, use that too.
Definitely do not put using namespace std; or any other namespace into headers files unless that is the purpose of that header.
Refrain from using macros if possible also.
It is generally fine to place using in a header file.
Is there a way I can get rid of using ... in the header file?
Yes: Don't depend on the declaration in the header, then you don't need to declare it. But as I stated, there is generally no need to do get rid of using in a header.
Is there a way I can get rid of ... gflag in the header file?
Define it in a source file instead.
I am writing a small library. Declaration of my classes, functions and others, that uses standard library are in a header file. I know that putting "using namespace" into header is a bad practic. May I put my code in separate namespace and then put "using namespace" into it?
Like this:
// header.h
namespace My
{
using namespace std;
// declarations
}
Will it be good?
Don't do it!
Simply use fully qualified names or using declaration for specific symbols that you want to use.
With this, You will just end up importing the contents of entire std namespace in your namespace My and essentially the header file header.h. Basically, it is going to give you namespace pollution with lot of unused symbols and also increase the compilation time of every translation unit where you include this header.
You may do that but it is not a good idea because this can lead to ambiguious names.
This question already has answers here:
Why is "using namespace std;" considered bad practice?
(41 answers)
Closed 1 year ago.
In all our c++ courses, all the teachers always put using namespace std; right after the #includes in their .h files. This seems to me to be dangerous since then by including that header in another program I will get the namespace imported into my program, maybe without realizing, intending or wanting it (header inclusion can be very deeply nested).
So my question is double: Am I right that using namespace should not be used in header files, and/or is there some way to undo it, something like:
//header.h
using namespace std {
.
.
.
}
One more question along the same lines: Should a header file #include all the headers that it's corresponding .cpp file needs, only those that are needed for the header definitions and let the .cpp file #include the rest, or none and declare everything it needs as extern?
The reasoning behind the question is the same as above: I don't want surprises when including .h files.
Also, if I am right, is this a common mistake? I mean in real-world programming and in "real" projects out there.
Thank you.
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.
Item 59 in Sutter and Alexandrescu's "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices":
59. Don’t write namespace usings in a header file or before an #include.
Namespace usings are for your convenience, not for you to inflict on others: Never write a using declaration or a using directive before an #include directive.
Corollary: In header files, don't write namespace-level using directives or using declarations; instead, explicitly namespace-qualify all names.
A header file is a guest in one or more source files. A header file that includes using directives and declarations brings its rowdy buddies over too.
A using declaration brings in one buddy. A using directive brings in all the buddies in the namespace. Your teachers' use of using namespace std; is a using directive.
More seriously, we have namespaces to avoid name clash. A header file is intended to provide an interface. Most headers are agnostic of what code may include them, now or in the future. Adding using statements for internal convenience within the header foists those convenient names on all the potential clients of that header. That can lead to name clash. And it's just plain rude.
You need to be careful when including headers inside of headers. In large projects, it can create a very tangled dependency chain that triggers larger/longer rebuilds than were actually necessary. Check out this article and its follow-up to learn more about the importance of good physical structure in C++ projects.
You should only include headers inside a header when absolutely needed (whenever the full definition of a class is needed), and use forward declaration wherever you can (when the class is required is a pointer or a reference).
As for namespaces, I tend to use the explicit namespace scoping in my header files, and only put a using namespace in my cpp files.
With regards to "Is there some way to undo [a using declaration]?"
I think it is useful to point out that using declarations are affected by scope.
#include <vector>
{ // begin a new scope with {
using namespace std;
vector myVector; // std::vector is used
} // end the scope with }
vector myOtherVector; // error vector undefined
std::vector mySTDVector // no error std::vector is fully qualified
So effectively yes. By limiting the scope of the using declaration its effect only lasts within that scope; it is 'undone' when that scope ends.
When the using declaration is declared in a file outside of any other scope it has file-scope and affects everything in that file.
In the case of a header file, if the using declaration is at file-scope this will extend to the scope of any file the header is included in.
Check out the Goddard Space Flight Center coding standards (for C and C++). That turns out to be a bit harder than it used to be - see the updated answers to the SO questions:
Should I use #include in headers
Self-sufficient headers in C and C++
The GSFC C++ coding standard says:
§3.3.7 Each header file shall #include the files it needs to compile, rather than forcing users to #include the needed files. #includes shall be limited to what the header needs; other #includes should be placed in the source file.
The first of the cross-referenced questions now includes a quote from the GSFC C coding standard, and the rationale, but the substance ends up being the same.
You are right that using namespace in header is dangerous.
I do not know a way how to undo it.
It is easy to detect it however just search for using namespace in header files.
For that last reason it is uncommon in real projects. More experienced coworkers will soon complain if someone does something like it.
In real projects people try to minimize the amount of included files, because the less you include the quicker it compiles. That saves time of everybody. However if the header file assumes that something should be included before it then it should include it itself. Otherwise it makes headers not self-contained.
You are right. And any file should only include the headers needed by that file. As for "is doing things wrong common in real world projects?" - oh, yes!
Like all things in programming, pragmatism should win over dogmatism, IMO.
So long as you make the decision project-wide ("Our project uses STL extensively, and we don't want to have to prepend everything with std::."), I don't see the problem with it. The only thing you're risking is name collisions, after all, and with the ubiquity of STL it's unlikely to be a problem.
On the other hand, if it was a decision by one developer in a single (non-private) header-file, I can see how it would generate confusion among the team and should be avoided.
I believe you can use 'using' in C++ headers safely if you write your declarations in a nested namespace like this:
namespace DECLARATIONS_WITH_NAMESPACES_USED_INCLUDED
{
/*using statements*/
namespace DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED
{
/*declarations*/
}
}
using namespace DECLARATIONS_WITH_NAMESPACES_USED_INCLUDED::DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED;
This should include only the things declared in 'DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED' without the namespaces used. I have tested it on mingw64 compiler.
I am writing a utility library which is made up of several "Packages". The classes in each package are contained in various namespaces. I have an idea as to how I can simplify the situation by automatically declaring using statements at the end of class declarations (see below), this will avoid having the programmer do it in a cpp file.
namespace Utility
{
class String
{
// Class Implementation
};
}
using Utility::String;
My understanding is that if the user includes the header String.h and String is in Utility then the programmer will want to use String. Obviously this could be bad if there are outside classes chain including a bunch of files which dirty up the namespace so I thought how about making it a #define instead.
namespace Utility
{
class String
{
// Class Implementation
};
}
#ifdef AUTO_DECLARE_NAMESPACE
using Utility::String;
#endif
That way, programmers that want this extended functionality can get it.
Would this a good idea or is there something I'm overlooking?
There is no point in using namespaces if you are just going to add a using declaration for each and every name declared in the namespace.
Let users of your header files decide how they want to use the headers. If someone wants to use a using declaration, let him do it in the .cpp file directly; this will make the code in that .cpp file clearer since it will be apparent where the name originated.
This seems at best pointless, and at worst annoying.
What is wrong with having developers decide which namespaces to use and what to qualify fully?
Honestly, I believe that's what the using namespace directive is for. There's no need for you to add this preprocessor mechanism, considering the using namespace directive does just that.
Couldn't you have another .h file with all your usings like my_lib_import_names.h and just #include that to get what you want?
You would probably have problem with classes not being declared but you could probably bypass it by using something like:
#ifdef UTILITY_STRING_H_
using Utility::String;
#endif
..
#ifdef UTILITY_SOMETHING_ELSE_H
using Utility::SomethingElse;
#endif
..
What do you think?
That way you could retain the "expected" behavior in your library .h but also have your the way you like. You also get to keep the benefit of the namespace over your classes (at the expense of having to maintain your new .h file).
I like the concept of C++ namespaces, because they help to keep the source code concise while avoiding name conflicts. In .cpp files this works very well, using the "using namespace" declaration. However, in header files this cannot be used, as it "breaks open" the namespace, meaning that the "using namespace" not only applies within the current header file, but to everything that is compiled thereafter. This partly nullifies the advantage of namespaces. Consider for example a header file in which the classes "ourlib::networking::IpAddress" and "ourlib::filesystem::Path" are frequently used.
Is there a way to limit the effect of the "using namespace"-declaration in header files?
You may put, most of frequently use classes in ::ourlib namespace like
namespace ourlib {
using networking::lpAddress;
}
So, if they unique in the project, most likely you would not have problem. So in, any
place in headers you would be able access lpAddress directly without putting in into
global namespace (I assume all your headers inside namespace ourlib)
No, it can't be done :(
You can just import single classes:
using ourlib::networking::lpAddress;
At least if I remember correctly ;)
This might pollute the global namespace still, though. I tend to just live with the long namespace prefixes in header files. This makes it easier to read the header file for other developers (since you don't have to lookup which class comes from which namespace).