Suppose you define a function inside the translation unit with the name of function exactly matching with any of the standard library function.
As the compiler first looks for the definition in the translation unit(s) and then in the library file, so will this cause to use the own version of the function definition or will it cause a diagnostic?
No, the names of functions within namespace std are not reserved - at least, not in the sense that using the same names outside of namespace std is forbidden.
However, placing names within namespace std (except in a few cases, such as specialising certain template functions) gives undefined behaviour.
If you are getting the compiler complaining about ambiguity when calling your functions, where one of the functions has the same name as yours but is in namespace std, then the cause is probably a using namespace std in your code. The effect of that, when the compiler encounters a name, is that both your functions and those in namespace std are valid matches. If the compiler has no reason to prefer one over the other (e.g. they accept the same types of argument) the code will not compile. In that case, the solution is to remove the using namespace std from your code - there is no way to undo the effects of using namespace std other than removing it.
I'm not sure if I understand the question correctly (correct me if I am wrong) but say you have a function like so:
void sort( // blah blah
Or declaring the std namespace using namespace std (which you should not be doing)
When you call sort(...) within your translation unit, the compiler overloads the definitions and in this case your function has precedence.
But if you are calling the standard library function by explicitly defining the std namespace (using the scope resolution operator) like so
std::sort( // blah blah
it will use the std library function instead.
That's the reason why people say using namespace std; in C++ is a bad practice.
Because the function definition gets conflicted when you use the same function name which is already defined inside the namespace std leading to many unrelated errors.
Read this thread for more details:-
Why using namespace std; in C++ is considered a bad practice?
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.
I am using only header files specific to C++ (e.g. <cstdlib>), however I still get globally-declared functions, and not just functions in the std namespace. Is there a way, perhaps a compiler switch, to prevent that?
For example, the following code:
#include <cstdlib>
float random() { return 0.0f; }
int main() { return 0; }
Fails to compile under linux, with the following error:
> g++ -c main.cpp main.o
main.cpp: In function ‘float random()’:
main.cpp:2:14: error: new declaration ‘float random()’
/usr/include/stdlib.h:327:17: error: ambiguates old declaration ‘long int random()’
or
> clang++ main.cpp -o main.o
main.cpp:2:7: error: functions that differ only in their return type cannot be overloaded
float random() { return 0.0f; }
/usr/include/stdlib.h:327:17: note: previous declaration is here
extern long int random (void) __THROW;
which is caused that stdlib.h "pollutes" the global namespace with its own random function.
Note, that I am not facing these problems when compiling on Windows, using Visual Studio.
<cstdlib> will always populate std namespace, and sometimes define global symbols, while <stdlib.h> will always define global symbols, and sometimes populate std namespace. This varies from implementation to implementation.
The standard writes:
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).
Which means, that the compiler is allowed to put those symbols into global scope and std namespace at the same time.
Therefore, we see no advantages to prefer one header file over the other. Because they are both very likely to pollute the global scope.
However, it is still necessary to use std namespace when #include <cstdlib>, and do not use std when #include <stdlib.h>, to make sure your code can compile for all compiler implementations.
Advice: Do not use names in standard libraries. First, they are not guaranteed to work. (Note: Few compiler implementations actually keep the global scope clean when you #include <csomething>, so never depend on this.) Second, it will confuse code readers and maintainers, because almost everyone will assume standard names are actually standard, no matter where they come from.
You can declare your functions in their own namespaces to prevent declaration collision.
namespace MyFunc
{
float random() { return 0.0f; }
};
In general you should try to avoid redeclaring in the first place.
You can do this by either using namespaces or by splitting up your source into files which can include cstdlib and others which can use a static version of your (name clashing) function.
If this is not an options then go on reading. But be aware that the following might be very platform specific.
By just having a look at my cstdlib and stdlib.h here at my place I noticed that there is a switch by which cstdlib decides if it includes stdlib.h or just declares abort, atext and exit in the std namespace.
Obviously you pull in the stdlib.h branch. Looking further into this file I noticed the macro __BEGIN_NAMESPACE_STD and later on __END_NAMESPACE_STD. Maybe you could use this, but it is (as the name suggests) some implementation internal macro and should not be set directly by you. However, it should be there for some reason so you might have luck with searching for it.
After some more search it turned out that random is one of several functions (and declarations) which are not wrapped into __BEGIN_NAMESPACE_STD. Therefore, this is not a solution to the problem. (I found another macro _GLIBCPP_USE_NAMESPACES which seems to be used internally as well to #define __BEGIN_NAMESPACE_STD namespace std {).
So to sum it up: This is no viable path and you should use one of the described workarounds.
The standard explicitly permits <c???> headers to bring names of C standard functions to the global namespace.
usually I would prefer to keep your function names different from what is defined as a standard .
For ex here one could use function name as myRandom instead of random so that I can inform the people , who would be maintaining my code later on , that the function being used is NOT the one defined as a standard.
This question already has answers here:
Why is "using namespace std;" considered bad practice?
(41 answers)
Closed 7 years ago.
Two ways to use the using declaration are
using std::string;
using std::vector;
or
using namespace std;
which way is better?
It depends.
If you want to inject a single name into another scope, the using-declaration is better, e.g.
namespace foolib
{
// allow vector to be used unqualified within foo,
// or used as foo::vector
using std::vector;
vector<int> vec();
template<typename T> struct Bar { T t; };
template<typename T>
void swap(Bar<T>& lhs, Bar<T>& rhs)
{
using std::swap;
// find swap by ADL, otherwise use std::swap
swap(lhs.t, rhs.t);
}
}
But sometimes you just want all names, which is what a using-directive does. That could be used locally in a function, or globally in a source file.
Putting using namespace outside a function body should only be done where you know exactly what's being included so it's safe (i.e. not in a header, where you don't know what's going to be included before or after that header) although many people still frown on this usage (read the answers at Why is "using namespace std" considered bad practice? for details):
#include <vector>
#include <iostream>
#include "foolib.h"
using namespace foo; // only AFTER all headers
Bar<int> b;
A good reason to use a using-directive is where the namespace only contains a small number of names that are kept intentionally segregated, and are designed to be used by using-directive:
#include <string>
// make user-defined literals usable without qualification,
// without bringing in everything else in namespace std.
using namespace std::string_literals;
auto s = "Hello, world!"s;
So there is no single answer that can say one is universally better than the other, they have different uses and each is better in different contexts.
Regarding the first usage of using namespace, the creator of C++, Bjarne Stroustrup, has this to say in §14.2.3 of The C++ Programming Language, 4th Ed (emphasis mine):
Often we like to use every name from a namespace without qualification. That can be achieved by providing a using-declaration for each name from the namespace, but that's tedious and requires extra work each time a new name is added to or removed from the namespace. Alternatively, we can use a using-directive to request that every name from a namespace be accessible in our scope without qualification. [...]
[...] Using a using-directive to make names from a frequently used and well-known library available without qualification is a popular technique for simplifying code. This is the technique used to access standard-library facilities throughout this book. [...]
Within a function, a using-directive can be safely used as a notational convenience, but care should be taken with global using-directives because overuse can lead to exactly the name clashes that namespaces were introduced to avoid. [...]
Consequently, we must be careful with using-directives in the global scope. In particular, don't place a using-directive in the global scope in a header file except in very specialized circumstances (e.g. to aid transition) because you never know where a header might be #included.
To me this seems far better advice than just insisting it is bad and should not be used.
using std::string; and using std::vector;.
Polluting the global namespace with a bunch of symbols is a bad idea. You should just use the std namespace prefix too, so you know that you're using standard library containers. Which is better than both options IMO.
If you are simply using the standard library and nothing else and never will be adding in any other libraries to your project, by all means, use using namespace std; - Whatever you feel more comfortable with in that situation. The convention of "never use using namespace std;" comes from the fact that multiple other libraries define things such as string, vector and such. It is good practice to never import the whole namespace, but it should cause no bothers in your case.
In the stlport library, I saw this code:
namespace std { }
namespace __std_alias = std;
1. Are they trying to nullify the standard std namespace in the first line?
2. Why in the world would they use a longer alias name in place of the original name?
You need the namespace "in scope" before you can declare an alias to it. The empty namespace std {} informs the compiler that the namespace exists. Then they can create an alias to it.
There are reasons for creating aliases besides creating a shortcut. For example, you can define a macro to "rename" the namespace -- consider the effect of #define std STLPORT_std. Having a alias allows you to access the original namespace provided that you play the correct ordering games with header files.
No, that just makes sure the namespace's name is available in the current scope. You can open and close namespaces at any point, without affecting the contents of the namespace.
I would guess, so they could easily change their library implementation to be in a namespace other than ::std (by changing __std_alias to alias something else). This would be useful, for example, if you want to test two implementations alongside each other.
It is rather annoying to get a compiler error that there is no such namespace as std... What is the compiler thinking? Of course it exists!
Well yes it does, but as with library features, it has to be declared first. That is what the first line is doing.
With the renaming of __std_alias it allows them to give a new alias to a namespace. You may decide to do this in your own code someday.
Perhaps you want to use shared_ptr in your code but do not want to dedicate your code to using namespace boost or std. So you can create an alias, and "point" it at either boost or std. Same with other features that are in boost libraries that later became standard.
This does not tie you to using this namespace for everything as you can have more than one alias, and you can have more than one pointing to the same real namespace.
Let's say we want to call our smart pointer library sml. We can do
namespace sml = boost; // or std
in one place in the code and #include <boost/shared_ptr.hpp> from that point in the code (same header).
Everywhere else in our code we use sml::shared_ptr. If we ever switch from boost to std, just change the one header, not all your code.
In addition to what D.Shawley said, forward declaring a class that's inside a namespace requires the same syntax:
namespace std
{
template <typename T>
class vector;
}
I knew the technique of using std::swap to enable via ADL the use of user defined swap functions, but I was not aware that this should be applied also to some other functions. For example I was writing abusively std::abs in template code wheras I should have used something like:
template <class Int> void f(Int i) {
using std::abs;
Int j = abs(i);
// ...
}
What standard function can you think of which should be used this way?
On a side note: g++ puts abs in the global namespace when including cstdlib (in fact ctsdlib includes stdlib.h (which defines the function abs) and does a #undef abs...), what does the standard says?
This is from the standard :
3.4.6 Using-directives and namespace aliases
[basic.lookup.udir]
When looking up a namespace-name in a using-directive or
namespace-alias-definition, only namespace
names are considered.
Therefore, you can use the keyword using to import variable, types and functions into the current namespace.
EDIT
You can import anything you like into the current namespace, but you should care for namespace polution, therefore try not to use using in headers, but only in the source files.
Ideally, you shouldn't be using this keyword. I use it sometimes when I have deeply nested namespaces.