JACH
JACH

Reputation: 1048

Using namespace to avoid name collisions

I was compiling one of the projects I work with, this time with VS2010, just to find out that one of the includes in windows.h has a typedef INPUT which was clashing with an export const string in the code I already have.

//winuser.h (line: 5332)

typedef struct tagINPUT {
    DWORD   type;

    union
    {
        MOUSEINPUT      mi;
        KEYBDINPUT      ki;
        HARDWAREINPUT   hi;
    };
} INPUT, *PINPUT, FAR* LPINPUT;

//foo.h

//stuff here
extern FOO_DLL_API const string INPUT;

Now, I don't use INPUT in the offending .cpp (and I do not own most of the code), and trying to minimize the impact, I did the following:

//myfile.cpp

#include <foo.h>
namespace windowsLib {    //I added this
#  include <windows.h>
}

using namespace windowsLib;

So far, this approach is working fine, but I wanted to ask you if you see potential problems with this approach, or if you have a better suggestion.

Edit:

I appreciate all the comments and explanations on why this is a bad idea. What I get from your comments is that I should change foo.h and put the contents into a namespace. However, by doing that, I would be affecting dozens of files, and some more, which will now require namespace qualifications.

Is there a way to do this "the right way" without touching all those files?

If I was the owner of the code, I would do this change and be done with it, but I have to propose a solution and get it approved and assigned to someone, etc. So it will be easier if the change is minimal.

Edit 2:

My final proposal was to split the class in two as follows:

//stub.cpp

#include <windows.h>

//Implementation of wrapper methods

//stub.h

class stub {
    //public wrapper methods
}

//myfile.cpp

#include <stub.h>
#include <foo.h>    

I'm accepting Benlitz answer since that suggestion would also solve the problem with the current minimal impact constrains I currently face. However, I thank you all for your comments.

Upvotes: 3

Views: 1219

Answers (4)

emsr
emsr

Reputation: 16373

Putting a namespace around windows.h sounds dangerous to me. It probably would hide stuff you need. Except you import the namespace in the next line anyway.

I would sooner put the namespace around foo.h:

namespace fooLib {
#include "foo.h"
}

using fooLib;

I guess this just shifts the problem from OS code to foo code but that seems safer to me.

Another approach might be to build a wrapper around foo that calls foo functions and returns foo globals in a separate little wrapper library. One that didn't need windows.h. This wrapper you might put in a namespace to prevent this from happening again.

I'm assuming here that you don't have the ability to rename things in foo.h or put the fooLib namespace around stuff inside foo.h.

If you can touch foo.h it would be better to rename INPUT in foo.h or put foo.h stuff in a namespace of its own. I think a fooLib namespace would have great (obvious) benefit.

Upvotes: 1

Benlitz
Benlitz

Reputation: 2002

It is a bad idea as explained in other answers. Here is an idea that might help you fix your issue:

//myfile.cpp

#define INPUT UnusedSymbol
#include "foo.h"
#undef INPUT

#include "windows.h"

This might work because INPUT is an extern variable in foo.h, so neither the compiler nor the linker would care about it as long as you don't use it in myfile.cpp. UnusedSymbol is a dummy name, you can write whatever name is not used in your source.

Upvotes: 1

Bo Persson
Bo Persson

Reputation: 92391

Not only is it not allowed by the language (assuming standard headers will be included inside a namespace), there is also the problem of calling any functions declared in <windows.h> and finding that the linker will look for them in namespace windowsLib.

Just doesn't work!

Upvotes: 3

Luchian Grigore
Luchian Grigore

Reputation: 258678

This seems like a bad idea at least.

1) If that's actually your code, there's no benefit from adding the namespace, since you have using namespace windowsLib; on the next line. Won't INPUT be ambiguous anyway?

2) You might include other headers that use stuff from windows.h and won't use the correct symbols. Imagine including a header that defines a function that returns INPUT. How's that gonna work out?

I suggest you play it safe and just rename your type.

Upvotes: 2

Related Questions