The following code will cause compile errors in g++4.4:
// File test.cpp
namespace A
{
#include <iostream>
}
int main()
{
return 0;
}
I have this requirement because some third party library comes without namespace protected, and if I directly include these headers, my namespace is polluted.
As a result, I tried to create namespaces for those libraries, but if the library includes some "std headers" the above approach will fail.
Can anybody help?
Thank You!
I believe 17.4.2.1 [lib.using.headers] forbids including standard library headers in a namespace :
A translation unit shall include a header only outside of any external declaration or definition, and shall
include the header lexically before the first reference to any of the entities it declares or first defines in that
translation unit.
I don't think there is anything you can do besides filing a request to the library author.
This approach will most likely lead you to trouble. You could approach the problem by manually including each such standard header before entering the namespace, and the include guards would take care of not re-including the header inside the namespace.
That would take care of your current error, but it would on the other hand break too many other things --if the library is precompiled then the symbols used in your code and the symbols in the binary library would be different symbols (libname::foo() used in your code, ::foo() defined in the binary). Even if the library is header only, any fully qualified access to the library within the library itself would break (void foo() { ::bar(); } where foo and bar are inside the library).
A valid approach that you might want to try (even if cumbersome, and requiring real work) would be writting a wrapper that is within it's own namespace, and uses the library. Then include your wrapper instead of the actual library headers.
My advice, on the other hand, would be ignoring the problem altogether. Declare your own objects within your namespaces and that would take care of the possible name collisions. As long as you keep away from using namespace statements you will be fine.
Use fully qualified names when using calls to standard libraries like std::cout instead of writing using namespace std;. This way, both can coexist.
Related
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.)
The Linux <ncurses.h> header defines the function meta, and the C++ metaprogramming library meta puts all its code in the global namespace meta.
How can I use both in the same C++ program (not necessarily the same TU but that would be nice)? Is there a way to work around the name collision?
I can think of two brittle workarounds, but they are easy to break:
Workaround A:
namespace linux {
#include <ncurses.h>
} // namespace linux
using linux::max_align_t; // ncurses assumes it is in the global namespace
#include <meta/meta.hpp>
compiles but will probably fail to link since the ncurses symbols are expected in the global namespace.
Workaround B:
#include <ncurses.h>
namespace cpp {
#include <meta/meta.hpp>
} // namespace cpp
is very brittle since it will only work as long as the meta library doesn't assume that any of its symbols are in the global namespace. That is, if the library needs to disambiguate internally a symbol and uses ::meta::symbol_name for that, this approach will break.
I would suggest workaround C: Isolate your code such that the meta library use and the ncurses use are in separate translation units in your project. This way in any particular translation unit there isn't one symbol being used as both a namespace and a global function.
I'm reasonably certain that neither A nor B will actually work, at least as given. You've pointed toward one of them, but I think it's the less likely of the two. There are two problems that are basically mirror images of each other.
If the code in ncurses is declared as extern "C" (typical for many C libraries that have been made to work with C++), surrounding them with a namespace won't actually work--an extern "C" declaration basically ignores namespaces and declares a function in the global namespace. The namespace won't change much of anything, and you'll still have a collision.
If the content of <ncurses.h> is not declared extern "C", then you'll run into the problem you cited: the library is built with functions in the global namespace, but the client code is seeing definitions for code in the linux namespace. Since the namespace affects the mangled name (that's how it prevents a collision) your code won't be able to link. All the linux::* functions will show up as unresolved externals.
To make this work, you need to assure that none of the library code is declared extern "C", and specify the namespace inside the header (and the library source files), and re-compile the library with these declarations, so the library and its client code agree on the namespace where that code resides.
All the entities (variables, types, constants, and functions) of the standard C++ library are declared within the std namespace.
Namespaces
Now if everything is 'declared' in std namespace they why are these fancy headers out there?
Have already checked this but it was not helpful enough.
Namespaces are kind of a way to organize our types. Keep all your math functions in the MyMath namespace, etc. It's also a way to separate out your types so that they don't clash with other types. So you can have both a MyTypes::string and an stl::string in your code. The std namespace is the one the STL has chosen for its stuff.
Header files contain the public interface of code. It gives you what it has available, which types and functions it declares and hopefully documentation in comments about how to use it. If you try to use code without including its corresponding header file, your code won't compile because it can't find the types. Headers may or may not contain code in namespaces.
As you may know, When you include something like #include "a.h" in b.cpp, everything inside a.h will be placed instead of #include "a.h" in b.cpp. So if a.h is 200 lines of code and your actual code is 10 lines of code, the code that will be compiled would be about 210 lines code. And compile time will be increased if your a.h is big or you included it several times.( Pay attention that if something is included inside of a.h this story repeats. )
Let's suppose that std library is inside one .h file and inside std namespace. Now it's really big and In each file that you are going to use one of std classes, even the smallest one, you have to include whole of it. It makes your program really big and the compile really slow.
The snippet you have is a requirement. The header files are where the standard library entities are actually declared. There is more than one header due to the size and diversity of the entities contained in the standard library. Essentially, the declaration are grouped according to functionality.
Headers and namespaces are effectively unrelated; one does not have anything to do with the other.
As such, one also does not make the other obsolete in any way.
Consider this declaration of std::string that you might find in <string>:
namespace std {
typedef basic_string<char> string;
}
The namespace is a categorisation for the names created (and used) by the declaration;
The header file is a categorisation for where to store the declaration on your hard disk.
There's no "redeclaration" whatsoever because the two concepts are unrelated.
BRIEF: is it ever safe to do
namespace Foo {
#include "bar"
}
Before you blithely say no, I think I have some rules that allow it fairly safely.
But I don't like them, since they require the includer to separately include all global scope headers needed. Although this mightr be tolerable, if we imagine including within a namespace to be just a special management feature.
And overall, externs and forward declarations just don't work well from within namespaces.
So I gues I am asking
a) What other gotchas
b) is there a better way
== A [[Header-only library]] ==
I like writing libraries. [[Header-only libraries and linker libraries]].
E.g.
#include "Valid.hpp"
defines a template Valid, for a simple wrapper type.
(Don't get bogged down in "You should use some standard library for this rather than your own. This is an exanple. I dunno if Boost or C++ have yet standardized this. I have been using wrappers since templates were added to C++.)
Also, let us say, it is a header only library, that defines, in Valid.hpp,
a print function
std::string to_string( const Valid& v ) {
std::ostringstream oss;
if( v.valid() ) { oss << v; }
else { "invalid"; }
return oss.str();
}
And because I think it is the right thing to do,
I have Valid.hpp include the headers it depends on:
Valid.hpp:
#include <iostream>
#include <sstream>
template<typename T>
class Valid {
private:
T value_;
bool valid_
...
};
...
std::string to_string( const Valid<T>& v ) { ...
So far, so good.
I can use Valid straightforwardly.
== Name collision - trying to use include within namespace to work around ==
But sometimes there is a collision.
Sometimes somebody else has their own Valid.
Namespaces to the rescue, right? But I don't want to change all of my existing code to use the namespace.
So, I am tempted, in a new project that has a collision, to do
namespace AG {
namespace Wrapper {
#include "lib/AG/Wrapper/Valid.hpp"
}
}
AG::Wrapper::Valid<T> foo_v;
...
PROBLEM: the headers included are no longer freestanding. Everything defined inside is no placed inside
namespace AG::Wrapper.
It's not hard to "fix".
Al we "must" do is include all the top level libraries that Valid.hpp depends on.
If they have include guards, they will not be re-included.
#include <iostream>
#include <sstream>
namespace AG {
namespace Wrapper {
#include "lib/AG/Wrapper/Valid.hpp"
}
}
AG::Wrapper::Valid<T> foo_v;
...
But it is no longer freestanding. :-(
Worse, sometimes the header-only library contains extern declarations and forward declarations of stuff outside itself.
These declarations get placed inside the namespace too.
In particular, if the extern declarayion is inside a function defined in the namespace.
I.e. sometimes we use extern and forward declarations, rather than included an entire header file.
These get included in the namespace.
Q: is there a better way?
== :: doesn't do it ==
Hint: :: doesn't do it. At least not all the time, not in gcc 4.7.2.
(Gcc's behavior in this has changed over time. Gcc 4.1.2 behaved differently.)
E.g.
Type var;
namespace Foo {
void bar() {
extern ::Type ::var;;
extern ::Type ::Foo::bar;
extern ::Type::foo ::bar; // see the ambiguity?
};
But it's not just the ambiguity.
int var;
namespace Foo {
void bar() {
extern int var;
};
works - Foo::bar'svar is equal to ::var.
But it only works because of the declaration outside the namespace.
The following doesn't work
header
int var;
cpp
namespace Foo {
void bar() {
extern int var;
}
}
although the following does:
header
int var;
cpp
void bar() {
extern int var;
}
}
Basically, what this amounts to saying is that
it is not a trivial refactoring to put functions inside a namespace.
Wrapping a namespace around a chunk of code,
whether or not it is #include'd,
is not a sufficient.
... at least not if there are extern or forward declarations.
And even if you
== Opinion against putting includes within namespaces ==
Stackoverflow folks seem to be against putting #includes inside namespaces:
E.g. How to use class defined in a separate header within a namespace:
... you should never write a #include inside a namespace. Where "never" means, "unless you're doing something really obscure that I haven't thought of and that justifies it". You want to be able to look at a file, and see what the fully-qualified names are of all the things in it. You can't do that if someone comes along later and sticks an extra namespace on the front by including from inside their namespace. – Steve Jessop Jan 6 '12 at 16:38
Overall question:
Is there any way, from deep within a namespace,
to say "and now here are some names that I am depending on from the outside world, not within the namespace."?
I.e. I would like to be able to say
namespace A {
void foo() {
// --- here is a reference to gloal scope extreren ...
I know this is an old question, but I want to give a more detailed answer anyway. Also, give a real answer to the underlying problem.
Here's just a few things that can go wrong if you include a header from within a namespace.
The header includes other headers, which are then also included from within the namespace. Then a different place also wants to include these headers, but from outside the namespace. Because the headers have include guards, only one of the includes actually goes in effect, and the actual namespace of the stuff defined in the headers suddenly subtly depends on the order you include other headers.
The header, or any of its included headers, expects to be in the global namespace. For example, standard library headers will very often (in order to avoid conflicts) refer to other standard stuff (or implementation details) as ::std::other_stuff, i.e. expect std to be directly in the global namespace. If you include the header from within a namespace, that's no longer the case. The name lookup for this stuff will fail and the header will no longer compile. And it's not just standard headers; I'm sure there are some instances of this e.g. in the Boost headers too.
If you take care of the first problem by ensuring that all other headers are included first, and the second problem by making sure no fully qualified names are used, things can still go wrong. Some libraries require that other libraries specialize their stuff. For example, a library might want to specialize std::swap, std::hash or std::less for its own type. (You can overload std::swap instead, but you can't do that for std::hash and std::less.) The way to do this is close your library-specific namespace, open namespace std, and put the specialization there. Except if the header of the library is included in arbitrarily deeply nested namespaces, it cannot close those namespaces. The namespace std it attempts to open won't be ::std, but ::YourStuff::std, which probably doesn't contain any primary template to specialize, and even if it did, that would still be the wrong thing to do.
Finally, things in a namespace simply have different names than things outside. If your library isn't header-only but has a compiled part, the compiled part probably didn't nest everything in the namespace, so the stuff in the library has different names than the stuff you just included. In other words, your program will fail to link.
So in theory, you can design headers that work when included within a namespace, but they're annoying to use (have to bubble up all dependencies to the includer) and very restricted (can't use fully qualified names or specialize stuff in another library's namespace, must be header-only). So don't do it.
But you have an old library that doesn't use namespaces, and you want to update it to use them without breaking all your old code. Here's what you should do:
First, you add a subdirectory to your library's include directory. Call it "namespaced" or something like that. Next, move all the headers into that directory and wrap their contents in a namespace.
Then you add forwarding headers to the base directory. For each file in the library, you add a forwarder that looks like this:
#ifndef YOURLIB_LEGACY_THE_HEADER_H
#define YOURLIB_LEGACY_THE_HEADER_H
#include "namespaced/the_header.h"
using namespace yourlib;
#endif
Now the old code should just work the way it always did.
For new code, the trick is not to include "namespaced/the_header.h", but instead change the project settings so that the include directory points at the namespaced subdirectory instead of the library root. Then you can simply include "the_header.h" and get the namespaced version.
I don't think it's safe. You put all your includes into the namespace Foo...
Imagine some of your includes include something from the std namespace... I cannot imagine the mess !
I wouldn't do that.
Header files are not black boxes. You can always look at a header you're including in your project and see if it is safe to include it inside a namespace block. Or better yet, you can modify the header itself to add the namespace block. Even if the header is from a third-party library and changes in a subsequent release, the header you have in your project won't change.
In C# one only uses an using directive for a namespace. In C++ like in this example below, one must do an include then use a namespace, why isn't it the same thing like in C# ?
#include <iostream>
int main()
{
using namespace std;
cout << "Hello world!" << endl;
return 0;
}
Because the compiler in C# works very differently than C++.
The quick version - C# uses references in a (vaguely) similar fashion as C++ uses the linker, and forward declarations. C++ requires forward declarations so it can compile each source file to a translation unit, then link all those units together. The C# compiler loads the code for your referenced assemblies, then compiles your whole assembly at once, and therefore doesn't need those sorts of forward declarations.
The long version -
C++
In C++, if you want to use code, you have to add it to the linker, and provide forward declarations. Header files contain forward declarations, and include files simply copy/paste that file into your source file.
This is because C++ has a mid-step called translation units, and produces object files. There are glued together by the linker.
In your example, #include <iostream> provides the forward declarations, and does so by including a header file (previously called "iostream.h", but now called "iostream"). This header file gets copy/pasted into your source code (along with all the headers that file includes, and so on). This all gets compiled down to a translation unit (object file), linked to the C++ runtime (as well as probably the C runtime, and maybe others), and turned into an executable.
C#
In C#, if you want to use code, you add a reference to the project or build file, or you simply add the C# file to the same project. No forward declarations are required, but you do have to reference the code, or have another source file in your current assembly that contains the code.
C# doesn't have the translation unit mid-step. It only produces assemblies.
When you reference System.dll, you already have the code available to you. You don't have to provide forward declarations, and therefore don't need to include any headers.
Both
You can use the using keyword to either pull an entire namespace into your current scope. In C++, you invoke using namespace std;. In C#, you invoke using System;
Then you can do things like:
std::cout << "test1\n";
cout << "test2\n";
Or
System.Console.WriteLine("test1");
Console.WriteLine("test1");
I forget if you can in C++, but in C# you can also alias namespaces:
using Ser = System.Runtime.Serialization;
...
class Blah : Ser.ISerializable {
Or alias types:
using ISer = System.Runtime.Serialization.ISerializable;
...
class Blee : ISer {
I normally wouldn't answer a question with so many useful answers, but nobody seems to have noticed "import" in your question. In C and C++, the "#include" directive is not the same as "import" in Java or "using" in C#. Literally, a #include directive simply adds lines you the compilation of the file containing the directive. Period.
There is no comparable feature to #include in most other compiler languages; but there is such a feature in nearly every useful assembler. C is a low-level language originally designed for portable implementation of operating system kernels, drivers and utilities. C++ is a higher-level language, but is built upon C. A deliberate design goal was to allow most C programs to compile with no source changes as legal C++ programs.
Keep that picture in mind as you study C++. It may help you understand how why it's put together the way it is.
The C++ standard library is much smaller than the frameworks for Java or C#, and all of it is defined within the std namespace. That means that the only "import" you need for the entire library is the "using namespace std;", which is what brings those names into view without explicit std:: prefixes; but only those names that have been #included into the current compilation.
If you don't use an include, then as far as the compiler is concerned, whatever is declared in that header doesn't exist. In order to use a function, the compiler must know that it exists. The using directive and the #include are totally tangental- you don't have to use a using at all and many more experienced programmers recommend against it.
the include directive just copy-pastes the source file into your progams, nothing more (in your code, for example, #include puts the source-file "iostream" that's in your C++ compiler install into your source code.
The using direcive, on the other hands, does exactly what the one in C# does.
The purpose of using namespace std; line is so you don't have to type out the full std::cout, std::endl every time. It will assume when you do use cout, endl, or any other function from the standard library without the std:: that you wanted to use the one from the standard library.
You can try this yourself, remove using namespace std; and try to compile. You should get errors. Then try to compile again using std::cout << "Hello world!" << std::endl; and it will work like before.
Check this out here:
http://www.cplusplus.com/doc/tutorial/namespaces/
It actually is similar in C#. Using is indeed only for namespaces, even in C# Try using something from an assembly you haven't referenced, it won't work no matter how many times you say using Foo.Bar. Adding the reference is similar to the include step in C++ (although not identical, C# makes "including" and "linking" a single step).