Currently I am working on a c framework and I want to embed a c++ package into it. However, there are lots of naming conflicts occurs. So I decided to to add a namespace to the C++ source. Now the question is should I move the #include "header.h" within namespace { } block? I just spent some time to figure out a bug which was resulted from the following codes.
Original C++ source
In a.h
#include <unistd.h>
struct File
{
void func(int fd);
};
In a.cpp
#include "a.h"
void File::func(int fd)
{
::close( fd );
}
And I added the namespace like this
New a.h
namespace MyAddedNameSpace
{
#include <unistd.h>
struct File
{
void func(int fd);
};
}
New a.cpp
#include "a.h"
namespace MyAddedNameSpace
{
void File::func(int fd)
{
::close( fd );
}
}
And compiler complains that ::close() has not been declared.
The reason Why I put the #include directive inside namespace block is because the c++ package I imported also use #ifndef flag to include header files as follows. So I think the easy way is to put all codes within namespace block {}
#ifndef
#include <header1.h>
#include <header2.h>
...
#else
#include <header3.h>
#include <header4.h>
...
#endif
Now I solved this problem by adding the extra line in cpp file
#include <unistd.h> //new added line
#include "a.h"
namespace MyNameSpace
{
void File::func(int fd)
{
::close( fd );
}
}
But I am not satisfied with this solution since unistd.h header has already been included in a.h, but inside the namespace MyAddedNameSpace, or should I added the prefix MyNameSpace to all the function calls where the compiler complain no such function declared ?
Thanks for the reply.
You SHOULD NOT place #include
directives inside your own namespace. What you have done is to place all of the contents of unistd.h
inside your namespace as well; thus what used to be (and should remain!) ::close()
is now declared as MyAddedNameSpace::close()
. This is NOT what you want.
Your "solution" of adding the line #include <unistd.h>
at the top of your .cpp file fixes the problem, but only for this one .cpp file. What you've done is included the library header the correct way (without your namespace), and then when your header (a.h) is included, it does #include <unistd.h>
again (this time within your namespace), but this time the include guards in that file prevent it from being processed again. So for this .cpp file you're OK, but any other file that does #include <a.h>
will have the same problem that you originally had.
There may be some rare occasion where you have a good reason for using #include
within your own namespace, but you will most likely be including one of your own headers (or some other file) - NOT a library header! - and even then, it's probably not the ideal solution.
In a.h
#include <unistd.h>
namespace MyAddedNameSpace {
struct File
{
void func(int fd);
};
}
In a.cpp
#include "a.h"
namespace MyAddedNameSpace {
void File::func(int fd)
{
::close( fd );
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With