I'm writing a library to use in my projects. In it, I was hoping to wrap the c standard library in my library's namespace and a cstd namespace to avoid having its functions in the global namespace. However, from a previous question I asked and from what I've tested, I can't just #include everything in a namespace. Is there any way to do this?
I doubt it, unless you wanted to rewrite everything.
The C language itself has no concept of namespaces, so everything the C standard library uses must rely on the fact that whatever it is looking for resides in the global namespace.
If you simply wrapped a namespace around your #includes, the compiler wouldn't be able to find anything because it wouldn't know what namespace to look in.
The usual approach would be to put the 3rd party includes in the implementation files to keep them from polluting your api.
myapi.hpp
void coolthing( int howcool );
myapi.cpp
#include <coollib.h>
void coolthing( int howcool )
{
coollib_coolthing( howcool );
}
Related
I would like to evaluate an algorithm with an available public code in my project. I have integrated the files the algorithm needs into my project: kodtree.h, kodtree.cpp, pinpolyhedron.h, and pinpolyhedron.cpp. However, the compiler complains about the ambiguous symbols. I changed the variable names which were ambiguous to something else and the compiler compiles it with no problem. This way does not look like an elegant way of fixing the issue.
I was thinking of using namespace but found out that, for example, the file kodtree.h has several externs.
Would putting them into namespaces cause me trouble since they can contain extern?
Could someone kindly let me know the things I should be aware of when creating namespaces for such libraries?
Is using namespace the right way of doing this?
Or is it better to create an interface class for this library and put everything, i.e., kodtree.h, kodtree.cpp, pinpolyhedron.h, and pinpolyhedron.cpp, inside that class and make them private?
What is the recommended way of doing this?
I would appreciate any tips.
Is using namespace the right way of doing this?
Yes, but not the way you try to go about it. Libraries should properly namespace themselves, but sometimes they can't or won't for various reasons. It's best to leave them be, unless you intend to write a full blown wrapper around the library code.
We can always apply a little discipline and namespace our own code. Simply put, we can do something like this in every one of our own source files1:
#include <some_library.h>
#include <my_other_project_header.h>
namespace ProjectName { namespace ModuleName {
// Your code here
}}
That way your code is nicely insulated from whatever you include. And barring any extern "C" things, there should be no conflicts. Whatever the library header drags in, it will not cause clashes with code you write inside your namespaces. All the while, your code can refer to project entities with at most one level of qualification (code in Module1 can refer to Module2::Foo, or to Module1::Bar as simply Bar). Beyond that you can always refer to things outside your Project namespace by fully qualifying things or by employing using declarations.
1: If your compiler supports C++17, it can be the more palatable:
namespace ProjectName::ModuleName {
}
I'm beginner at C++ so if the answer is obvious it possibly is the one I'm looking for. I was reading the second response in this thread and got confused.
#include <algorithm>
#include <cassert>
int
main()
{
using std::swap;
int a(3), b(5);
swap(a, b);
assert(a == 5 && b == 3);
}
What I don't get is "This is just a defined function. What I meant was, why it is not directly built-in" but there was no need to include a new library so isn't it built-in? Does the std library automatically get imported (if yes, why doesn't the namespace automatically get set to std)?
"This is just a defined function. What I meant was, why it is not directly built-in" but there was no need to import a new library so isn't it built-in? Does the std library automatically get imported (if yes, why doesn't the namespace automatically get set to std)?
Well, by defined function it means, most likely that the function is already pre-written, and defined in the library, it isn't directly built-in probably because it was designed that way; only core essentials were included in the language, and everything else is in a library so the programmer can import what they want.
By built-in, usually it's a keyword, like for or while.
And no, std isn't automatically imported since it's designed so the programmer can choose what namespaces they want, like custom namespaces or std. An example of this being bad to automatically have std is this:
Say you automatically defined std, then you wanted to do using namespace foo;, now if foo also had function cout, you would run into a huge problem, like say you wanted to do this;
// code above
cout << "Hello, World" << endl;
// code below
how would the compiler which namespace function to use use? the default or your foo namespace cout? In order to prevent this, there is no default namespace set, leaving it up to the programmer.
Hope that helps!
This is just a defined function. What I meant was, why it is not directly built-in" but there was no need to include a new library so isn't it built-in?
The C++ library is a part of C++, by definition. However, it is not a part of the core language. C++ is a huge, huge language. Making it so the compiler knew every nook and cranny of the language right off the bat would make the compiler huge and slow to load. The philosophy instead is to keep the core somewhat small and give programmers the ability to extend the functionality by #including header files that. specify what they need.
Why doesn't the namespace automatically get set to std?
That would essentially make all kinds of very common words into keywords. The list of words you shouldn't use (keywords, global function in C, words reserved by POSIX or Microsoft, ...) is already huge. Putting the C++ standard library in namespace std is a feature. Putting all of those names in the global namespace would be a huge misfeature.
In your code, you have the line:
using std::swap;
So the call to swap doesn't need std::. For assert, it was defined as a macro, so it also would not need std::. If you did not use using, then other than macros, you would have to use std:: to refer to functions and objects provided by the standard C++ library.
The standard C++ library normally get linked into your program when you compile your program to create an executable. From this point of view, you might consider it "built-in". However, the term "built-in" would usually mean the compiler treats the word swap like a keyword, which is not the case here. swap is a template function defined in the algorithm header file, and assert is a macro defined in cassert.
A namespace is a convenience to allow parts of software to be easily partitioned by name. So if you wanted to define your own swap function, you could put it into your own namespace.
namespace mine {
template <typename T> void swap (T &a, T &b) { /*...*/ }
}
And it would not collide with the standard, or with some library that defined swap without a namespace.
So, I find myself in the need of libc in my C++ program. However, I do not like the idea of sprinkling it all over the global namespace. Ideally, I'd like to force the entirety of libc into the std:: namespace so I'd have to do std::memcpy rather than memcpy.
Is this possible? And how? I'm willing to use compiler-specific macros if needed (I target only MS VC++ 10.0 and GCC 4.6).
Edit: I do literally mean 'force the declarations into std' - so that they are uncallable without the std:: prefix. Also, I am including cstdio, not stdio.h.
Thanks!
You cannot do this, unless it's already done.
The namespace std is reserved to the Standard Library, it is forbidden to add new members to this namespace. Therefore, if the C-headers are not already embedded within std, then you have no choice but to accept it.
On the other hand, you can perfectly create a new namespace, cstd, and bring the symbols from the global namespace in it with using directives... but it won't make them disappear from the global namespace.
I do literally mean 'force the declarations into std' - so that they are uncallable without the std:: prefix.
You can't do this if your implementation exposes the names in the global namespace. You can use the <cXXX> headers and then use std:: yourself.
This is, perhaps, unfortunate, but it is a consequence of C compatibility, since C does not understand namespaces. C++ has traditionally maintained many kludges and sacrifices for C compatibility.
Make wrapper includes
//stdlib.hpp
namespace std
{
#include <stdlib.h> //edit: changed from cstdlib to stdlib.h
}
If the linker hates this try just declaring the functions you want:
namespace std{ extern "C" {
int memcpy( void *out, const void *in);
} }
The reason some (most?) C++ compilers have the C functions in the global namespace, is simply that they have to use the existing operating system functions. For example, the file functions might not be a separate C library, but the file handling of the OS.
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.
Why do we need both using namespace and include directives in C++ programs?
For example,
#include <iostream>
using namespace std;
int main() {
cout << "Hello world";
}
Why is it not enough to just have #include <iostream> or just have using namespace std and get rid of the other?
(I am thinking of an analogy with Java, where import java.net.* will import everything from java.net, you don't need to do anything else.)
using directives and include preprocessor directives are two different things. The include roughly corresponds to the CLASSPATH environment variable of Java, or the -cp option of the java virtual machine.
What it does is making the types known to the compiler. Just including <string> for example will make you able to refer to std::string :
#include <string>
#include <iostream>
int main() {
std::cout << std::string("hello, i'm a string");
}
Now, using directives are like import in Java. They make names visible in the scope they appear in, so you don't have to fully qualify them anymore. Like in Java, names used must be known before they can be made visible:
#include <string> // CLASSPATH, or -cp
#include <iostream>
// without import in java you would have to type java.lang.String .
// note it happens that java has a special rule to import java.lang.*
// automatically. but that doesn't happen for other packages
// (java.net for example). But for simplicity, i'm just using java.lang here.
using std::string; // import java.lang.String;
using namespace std; // import java.lang.*;
int main() {
cout << string("hello, i'm a string");
}
It's bad practice to use a using directive in header files, because that means every other source file that happens to include it will see those names using unqualified name lookup. Unlike in Java, where you only make names visible to the package the import line appears in, In C++ it can affect the whole program, if they include that file directly or indirectly.
Be careful when doing it at global scope even in implementation files. Better to use them as local as possible. For namespace std, i never use that. I, and many other people, just always write std:: in front of names. But if you happen to do it, do it like this:
#include <string>
#include <iostream>
int main() {
using namespace std;
cout << string("hello, i'm a string");
}
For what namespaces are and why you need them, please read the proposal Bjarne Stroustrup gave 1993 for adding them to the upcoming C++ Standard. It's well written:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0262.pdf
In C++ the concepts are separate. This is by design and useful.
You can include things that without namespaces would be ambiguous.
With namespaces you can refer to two different classes that have the same name. Of course in that case you would not use the using directive or if you did you would have to specify the namespace of the other stuff in the namespace you wanted.
Note also that you don't NEED the using - you can just used std::cout or whatever you need to access. You preface the items with the namespace.
In C++ #include and using have different functions.
#include puts the text of the included file into your source file (actually translation unit), namespaces on the other hand are just a mechanism for having unique names so that different people can create a "foo" object.
This comes from C++ not having the concept of a module.
Keep in mind that namespaces in C++ are open, that means that different files can define different parts of the same namespace (sort of like .NET's partial classes).
//a.h
namespace eg {
void foo();
}
//b.h
namespace eg {
void bar();
}
The include is defining the existence of the functions.
The using is making it easier to use them.
cout as defined in iostream is actually named "std::cout".
You could avoid using the namespace by writing.
std::cout << "Hello World";
These keywords are used for different purposes.
The using keyword makes a name from a namespace available for use in the current declarative region. Its mostly for convenience so that you do not have to use the fully qualified name all the time. This page explains it in some detail.
The #include statement is a pre processor directive and it tells the preprocessor to treat the contents of a specified file as if those contents had appeared in the source program at the point where the directive appears. That is, you can think of this statement as copying the included file into the current one. The compiler then compiles the entire file as if you wrote all the code in one big file.
As pointed out, C++ and Java are different languages, and do somewhat different things. Further, C++ is more of a 'jest grew' language, and Java more of a designed language.
While using namespace std; isn't necessarily a bad idea, using it for all namespaces will eliminate the whole benefit. Namespaces exist so that you can write modules without regard to name clashes with other modules, and using namespace this; using namespace that; can create ambiguities.
I think the other answers are missing the point slightly. In all of C++, Java and C#, the using/import thing is entirely optional. So that's not different.
And then you have to do something else to make code be visible anyway, in all three platforms.
In C++, you minimally have to include it into the current translation unit (good enough for many implementations of vector, string, etc.), often you have to add something to your linker as well, although some libraries do that automatically based on the include (e.g. boost when building on Windows).
And in C# you have to add a reference to the other assembly. That takes care of the equivalent of includes and link settings.
And in Java you have to ensure the code is on the classpath, e.g. adding the relevant jar to it.
So there are very closely analogous things required on all three platforms, and the separation between using/import (a convenience) and actual linkage resolution (a requirement) is the same in all three.
You need to understand namespaces if you want to truly understand this.
With include you are just including the header file.
With using namespace you are declaring you are using a given namespace that contains stuff such as cout. so if you do this:
using namespace std;
to you use cout you can just do
cout << "Namespaces are good Fun";
instead of:
std::cout << "Namespaces are Awesome";
Note that if you do not #include <iostream> you won't be able to use neither std::cout nor cout in your declarations and so forth because you're not including the header.
One liner (not that this is something new :)):
using std allows you to omit std:: prefix, but you cannot use cout at all without iostream.
Even Stroustrup refers to the #include mechanism as somewhat hackish. However it does make separate compilation much easier (ship compiled libraries and headers instead of all source code).
The question really is "why did C++ -- after it already had the #include mechanism -- add namespaces?"
The best example I know of about why #include isn't enough comes from Sun. Apparently Sun developers had some trouble with one of their products because they had written a mktemp() function that happened to have the same signature as a mktemp() function that was included through from a file that was itself included through a header the project actually wanted.
Of course the two functions were not compatible, and one could not be used as a substitute for the other. On the other hand, the compiler and linker did not realize this when building the binary, and sometimes mktemp() would call one function, and sometimes it would call another, based on the order different files were compiled or linked.
The problem stems from the fact that C++ was originally compatible with -- and essentially piggy-backed on top of -- C. And C has only a global namespace. C++ solved this problem -- in code that is not compatible with C -- through namespaces.
Both C# and Java (1) have a namespace mechanism (namespace in C#, package in Java), (2) are usually developed through IDEs that handle referring to binaries for the developer, and (3) don't allow freestanding functions (a class scope is something of a namespace, and reduces the risk of polluting the global namespace) so they have a different solution to this problem. However, it is still possible to have some ambiguity regarding which method you're calling (say, a name clash between two interfaces that a class inherits), and in that case all three languages require the programmer to clearly specify which method they're actually looking for, usually by prepending the parent class/interface name.
In C++, the include directive will copy and paste the header file into your source code in the preprocessing step. It should be noted that a header file generally contains functions and classes declared within a namespace. For example, the <vector> header might look similar to something like this:
namespace std {
template <class T, class Allocator = allocator<T> > class vector;
...
}
Supposing you need to define a vector in your main function, you do #include <vector> and you have the piece of code above in your code now:
namespace std {
template <class T, class Allocator = allocator<T> > class vector;
...
}
int main(){
/*you want to use vector here*/
}
Notice that in your code the vector class is still located in the std namespace. However, your main function is in the default global namespace, so simply including the header will not make the vector class visible in global namespace. You have to either use using or do prefixing like std::vector.