Is there anything that can be done about looong symbols that need to be referenced in header files, e.g. ABDEFGHIJ::ZXCBVB::AWEDADSDEM::GFGBKGDF::Tools::Item? I know in header files you aren't supposed to using using because it messes up anybody who includes it.
The only working feature that cleans up after itself that I can even think of would be #define+#undef but that seems terrible.
Is there a new feature that solves this that I'm not aware of? I'm also interested in any popular proposals. Maybe using with a bracketed block syntax, to let me restrict the effect to just my header...?
It's not good practice to have a using namespace using directive at global scope in a header file. There are a number of less drastic things you can do that are fairly benign however.
Inside an inline or template function in a header, you can use a using directive without affecting anyone else. This saves you having to qualify all the names in a non-trivial function body.
As Maksim Solovjov suggests, you can use namespace aliases to cut down on typing, with the caveat that a namespace alias at global scope will introduce that alias to anyone including your header so that may not be desirable.
C++11 introduced type aliases and alias templates which can be used in a header at class scope, function scope or namespace scope (you may still want to avoid using them at global scope) to give a shorter name to types. This is particularly useful when dealing with template types with long names like e.g. std::map<std::string, std::vector<std::function<float(float)>>>
C++11 and 14 type deduction through the auto keyword can greatly reduce the need to name long types in headers, whether function return types, local variables or parameters to lambdas.
C++11 decltype can also be useful to avoid saying the names of long types in certain situations.
Here is what I feel.
First of all you should create your own namespaces. Then you can draw in other namespace symbols without polluting the global namespace.
If the namespace you are accessing is truly massive (like std) then I would always either use the std:: qualifier or declare the types explicitly:
namespace my_project {
std::string s; // qualify
// or declare specific types
using std::string;
} // my_project
If the namespace is from your own project or a relatively small library then I see no reason not to inject the whole namespace into your own (never into the global namespace).
namespace my_project {
using namespace xmltools; // never do this in global namespace
// use without prefix here
} // my_project
The key is to use your own namespaces. Then what you do inside them will have less affect on people using your headers.
I think the main point is to remember that if someone injects the symbols from your namespace into their own they should not be surprised by what it contains.
So if my library builds on another library it may be normal for my library to contain the type symbols from the other library and someone injecting my namespace into theirs would also expect that.
You can have namespace aliases:
namespace fbz = foo::bar::baz;
However, you would introduce fbz to every file that includes your header.
Related
When using a header which has a format <cname>, an implementation will put names into std namespace. And it may put names into the global namespace as well, as it is described here:
[ Example: The header <cstdlib> assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. [...] — end example ]
Is there a (maybe compiler dependent) way to circumvent/disable this behavior (I'm open to any tricky solution)? I'd like to use names from std only, and I'd like to have an error/warning when using names from the global namespace:
#include <cmath>
double a = cos(0.5); // I'd like to have an error here, because std:: is missing
The reasons:
It is hard to write a portable code, if it may use names from the global namespace, as these names may be not available in other compilers. It is much cleaner to use everything from std, and not use the global namespace at all
cos(0.5f) does a different thing whether std:: is prefixed or not (float vs double result).
Since tricky solutions are fine...
Use a C++ parser, e.g. Clang, and write a tool that parses the header file, collects all the function definitions, and then compares that set against all definitions and calls to global functions.
Of course, it will also pick up cases where someone has defined or called a function with the same name as the standard ones, but you will probably want to avoid that as well anyway.
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?
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.
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.
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.
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.)
I've easily gotten myself into the habit of prefixing standard identifiers with std:: instead of sticking in a using namespace std;. However, I've started getting into C# and I've noticed that it's very normal to add in whatever using directives are necessary, i.e., you'd see:
using System;
Console.Write("foo");
instead of:
System.Console.Write("foo");
Apparently, as I found out from a C# question on this topic, that usage comes from the fact that individual system namespaces in C# are much, much smaller than std is in C++, and therefore eliminates the problems associated with name clashes, as there is much less likelihood (and you can just find-replace it with a fully qualified name if a library updates with a name-clash), and eliminates the problems associated with a crapload of Intellisense options appearing, as the namespaces are small enough to handle.
The question, then, is that if these are the standing reasons to make use of using directives in C#, is the same true for C++? Is it generally acceptable to apply this to smaller third-party namespaces, as well as your own smaller namespaces?
Now I realize that this might cause a bit of controversy, I want to take this moment to ask that it doesn't turn into an argument. A good answer should include a basis, i.e., advantages or disadvantages, and how using one way over the other really makes a worthwhile difference.
The reason I ask this is to clear up the issue, and possibly remove the notion that using directives in C++ have to be a bad thing. Sure longer namespace names can be cut down with a namespace alias if necessary, and fully qualified names can still be used if needed, but sometimes a using directive greatly eases accessing some members such as user-defined literal operators, which, to my knowledge, have no form of ADL, meaning that you either have to use a using directive, or call the operator method by the function syntax, defeating the whole purpose of using the operator in the first place.
For example, I had a namespace (that includes a structure representing a keyboard key, along with a literal suffix as a readable alternate means of access:
"caps lock"_key.disable();
The problem here is that unless you have previously inserted using namespace Whatever; or using Whatever::operator"" _key;, the code won't compile, which is bad news for the user.
Using directives have obvious problems when std is involved or when used in such a way in a header that they bring unwanted extras for the user of that header, but is it justified to use them for other namespaces when contained within a smaller scope than whatever includes a header? The keystrokes saved from not having to type each qualifier each time do add up, and with today's Intellisense capabilities, finding out which namespace an unqualified identifier belongs to is as easy as mousing over it.
I think the rules about using declarations in C++ are rather simple:
NEVER write "using namespace anything;" in the global scope of a header, especially one that is likely to be reused by other programs (e.g. when writing a library). It pollutes the global scope of all subsequent headers with the symbols of this namespace, which defeats the entire purpose of namespaces, and can create unforeseen name clashes later on.
In the .cpp files and inner scopes of headers (e.g. inline function scopes), you can be "using" whatever namespaces you want, as it won't affect any other file. Just do whatever is more convenient for you and try to be reasonably consistent within a project.
EDIT: for the _key problem, simply define this operator in its own namespace and tell users to import it. This way they won't need to type out the operator declaration.
namespace something {
class key { ... };
}
namespace key_suffix {
something::key operator"" _key() { ... }
}
// user code
void some_function() {
using namespace key_suffix;
"caps lock"_key.doSomething();
}
I am using two large libraries (GUI & network) and I can happily do
using namespace FirstLib;
using namespace SecondLib;
Except for 1 single class called Foobar where names clash.
I my code, I do not use FirstLib::Foobar. Is there a way to say "in my code, whenever you see Foobar, think SecondLib::Foobar ?
using namespace is evil! Namespaces were made to prevent such problems as you have! But that said, try:
using namespace FirstLib;
using namespace SecondLib;
using SecondLib::Foobar;
or even (for some compilers):
using namespace FirstLib;
using namespace SecondLib;
typedef SecondLib::Foobar Foobar;
It's strange nobody suggested to replace the full namespace use by the list of used class names. This solution is even in the C++faq (where I should have thought to look first).
If we cannot say
include all FirstLib, but remove SecondLib::Foobar
We can use using-declarations of the exact elements we need:
using FirstLib::Boids;
using FirstLib::Life;
// no using FirstLib::Foobar...
You've basically answered your own question. You must explicitly say which class you want to use, so you must do SecondLib::Foobar whenever you use that class.
You have to pick one of these namespaces and get rid of the 'using', and explicitly call out all the class names. C# has a way around this, but C++ does not afaik...
I don't think there's a way of excluding names. You either bring in the whole lot, or each one individually. Even when you bring in the whole lot, you can always disambiguate conflicting names by qualifying them fully.
However, you could use typedef to rename the offending class:
typedef Lib2::FooBar FooBaz;
And I guess, with a conflicting function, you could use a function pointer to "rename" the conflicting one.
I guess it's kind of a non-solution. I can understand the occasional motivation to use using declarations - sometimes there are indeed many different names that you'll use all over the place - but if just one is conflicting: be explicit. It would be confusing to anyone familiar with the libraries anyway, seeing that both namespaces are imported.
Also, using declarations respect scope: you can make one namespace visible in one function, but not the other namespace - assuming you don't even use it in that function.
Have you tried:
using SecondLib::Foobar;
?
If you load all elements from both namespace to current scope by use of using namespace directove:
using namespace FirstLib;
using namespace SecondLib;
and there is potential that some of the names in those namespace may clash, then you need to tell compiler explicitly which of the element you want to use, in current scope, by use of using declaration:
using SecondLib::Foobar;
As the C++ standard says:
7.3.3 The using declaration
1 A using-declaration introduces a
name into the declarative region in
which the using-declaration appears.
That name is a synonym for the name of
some entity declared elsewhere.
This line requests compiler to think SecondLib::Foobar whenever it sees Foobar for the rest of current scope in which the using declaration was used.
The using directive and declaration is very helpful, but they may cause problems as the one you're dealing with. So, it's a good idea to narrow use of any form of using to minimal scope possible. You can use the directive using namespace in scope of other namespace
namespace MyApp {
using namespace ::SecondLib;
}
or even a function. The same applies to using declaration. So, it's a good idea to narrow the scope of use of any of them:
void foo()
{
::SecondLib::Foobar fb;
}
It may seem tedious, but it is only when you type, though you most likely use intellisense-enabled editor, so cost is really small, but benefits are large - no confusions, readable code, no compilation issues.
It's also a very good idea to NOT to use using namespace in header scope. See Header files usage - Best practices - C++
My own tip: do use full qualification whenever you need to use any of these types
When using C++ namespaces, do you prefer to explicitly name them, like this:
std::cout << "Hello, world!\n";
Or do you prefer using namespace:
using namespace std;
cout << "Hello, world!\n";
And if if you prefer the latter, do you declare your usings at file or function scope?
Personally I prefer to explicitly name them - it's more typing but when using a mixture of namespaces (e.g. std and boost) I find it more readable.
I use always explicit ones. Writing std does not hurt me and I clearly see where is it from. It's useful when you have some legacy project to take care of with it's own "strings", "vectors" etc to maintain. The more information the code carries with it, the better.
Extra typing is not the issue here. The problem with explicitly qualified names is the visual clutter. Let's face it, C++ syntax is untidy. No need to make this worse by needlessly making names longer and sprinkling the code generously with ::s.
I'm with Jeff Atwood: The Best Code is No Code At All. This is so true.
Namespace imports are a great way of reducing clutter with no drawback: As long as the scope of opened namespaces is reduced to a single compilation unit1, name conflicts, should they appear, can be resolved easily.
Why explicit names should (in general) be more readable has always been a mystery to me. The readers should generally know the code good enough to be able to deduce semantics. If they aren't, the code needs fixing anyway.
1) Corollary: no using in headers!
I always use using namespace for std & boost. Everything else I tend to use an explicit namespace unless it is used so much that it would clutter up the code.
In headers, I never use using namespace to avoid polluting the global namespace of the #including source.
My general rule is always explicitly use the namespace in headers, and usually use using in the code. The reason for the former is to make it explicitly clear in every part of the definition what is being used, and the reason for the latter is that it makes it easy to use replacements from another namespace if that becomes necessary. i.e. if we want to start using foo::string instead of std::string we just need to update the header and the using statement rather than replacing every instance of std::string with foo::string in the code.
Of course, that is less useful for classes that reside in the std:: namespace, since even if you replace one class you're still likely to use others in std, and may run into ambiguity issues, but that was just an example.
using and using namespace are Very Very useful to render the code more readable - remove clutter.
But in any case where it makes it harder to find out where a symbol comes from, I refuse importing it's whole namespace.
I try to limiit the scope of the imported namespaces:
void bar() {
// do stuff without vector
{ using std::vector;
// do stuff with vector
}
// do stuff without vector
}
For "generally known" libraries, like std, I would dare using using namespace std. There is reason to believe everyone reading this code knows these symbols.
As a sidenote, the using keyword is also used to indicate that a derived class also exports the overloaded members of its superclass.
class A {
void f( A );
void f( bool );
};
class B : public A {
using A::f; // without this, we get a compilation error in foo()
void f(bool);
};
void foo() {
B b;
b.f( A() ); // here's a compilation error when no `using` is used in B
}
I only use explicit namespaces when there's some ambiguity. It is more readable, but the extra typing is too tedious, and you have to assume other developers have a baseline level of familiarity with standard libraries.
The only other times I spell out a namespace are when I'm only using it once or twice, like adding in a quick debug statement, or if I'm using some non-standard library.
I typically declare the namespace at file scope, but if you're mixing namespaces it might make sense to put the declaration closer to the point where it's used, in function scope.
using at function scope, or if the function is very small (often is), just explicit namespace
I tend to explicitly import the names that I need at the top of the .cpp file, so...
using std::cout;
using std::endl;
etc...
That way I have control over the names that I use and it's easy to see where they come from and the code isn't cluttered at the point of use.
In the rare cases where I am using two names from different namespaces I fully qualify them at the point of use.
I always use fully qualified names in headers and hardly ever use 'using namespace x' anywhere...