Sign in to follow this  
littlekid

How to get around thoes system defines

Recommended Posts

littlekid    229
Hi I am facing a problem with thoes defines by the system header files such as winbase.h I have a method in a class: class MyClass { public: void CreateFile(); }; However in winbase.h CreateFile is define to be CreateFileW due to the unicode stuff. And being a #define thing, it is making my method name change too. Is there anyway to avoid this problem, other than changing my method name? I understand that i can #undef it, but that would cause problems to people who wishes to use the actual CreateFile function by windows.

Share this post


Link to post
Share on other sites
Evil Steve    2017
This is just one of those annoying things unfortunately.

So long as you #include your header before any Windows headers, you'll be fine - but you need to ensure that the users of your class do the same.
EDIT: Ignore that, see mattd's point below.

Personally, I'd rename the method if possible. In this case, perhaps something a little more descriptive would be better, such as CreateSettingsFile()?

[Edited by - Evil Steve on November 6, 2009 4:29:48 AM]

Share this post


Link to post
Share on other sites
mattd    1078
Quote:
Original post by Evil Steve
So long as you #include your header before any Windows headers, you'll be fine - but you need to ensure that the users of your class do the same.

#include "MyClass.h"
#include <windows.h>

int main() {
MyClass c;
c.CreateFile();
}
?

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by mattd
Quote:
Original post by Evil Steve
So long as you #include your header before any Windows headers, you'll be fine - but you need to ensure that the users of your class do the same.

#include "MyClass.h"
#include <windows.h>

int main() {
MyClass c;
c.CreateFile();
}
?
Ah yes, I'm an idiot - ignore that bit...

Share this post


Link to post
Share on other sites
Codeka    1239
You can also make sure you always #include <windows.h> before anything else (e.g. by putting in a precompiled header). That way, CreateFile will still become CreateFileW, but at least it'll be consistent :-)

You can also get around it with a non-CamelCase naming convention, but that might be a bit much to ask...

Share this post


Link to post
Share on other sites
_Unicron_    438
I think using a better name is the best solution.

Would it also be possible to use #undef CreateFile in your class
header file? Although this may have other repurcussions that I
am unaware of.

Share this post


Link to post
Share on other sites
littlekid    229
Thanks for the replies :), i guess i have to change my method name. Ahh i hope windows put all their functions in a namespace or something that can solve this problem =)

Share this post


Link to post
Share on other sites
phresnel    953
Quote:
Original post by littlekid
Thanks for the replies :), i guess i have to change my method name. Ahh i hope windows put all their functions in a namespace or something that can solve this problem =)


You cannot solve #define aches with namespaces =(

Share this post


Link to post
Share on other sites
littlekid    229
Quote:
Original post by phresnel
Quote:
Original post by littlekid
Thanks for the replies :), i guess i have to change my method name. Ahh i hope windows put all their functions in a namespace or something that can solve this problem =)


You cannot solve #define aches with namespaces =(


hmm idiot me, thats true. hmm...well would something like that work??

like:

namespace windows_system_a
{
void CreateFile(char* );
};

namespace windows_system_w
{
void CreateFile(wchar_t* );
};

#ifndef UNICODE
#define windows_system windows_system_a
#else
#define windows_system windows_system_w
#endif

I am not sure if this works, but maybe it can greatly reduce the number of defines?? and there won't be so many clashes with the windows files =)

Share this post


Link to post
Share on other sites
magic_man    54
This is an issue with quite frankly pisses me off and it is done by development teams that do not think about things. Take std::max and windows max macro for an example, yes you can use another define to correct it or enclose std::max in braces but it is just evil, who every thought max was a good name for a macro needs taken outside and face at best some rotten fruit for a decade. What ever happened to the normal practice of using all caps?
Just like header guards should be unique so must all macros which are not part of the language standard. It does not take much to try and do this just pre or postfix the macro with the project acronym, MS_CreateFile or better still MS_CREATEFILE for example. This is something which teams still do not do today and hit me again the other day whilst trying to use two different testing frameworks to do different things with until both of the used ASSERT_EQUAL. Now granted Microsoft are not doing to do this for macros which have been used for years and would break code but it should be done for any newly defined macros.
/rant over.

Share this post


Link to post
Share on other sites
Codeka    1239
Quote:
Original post by magic_man
Now granted Microsoft are not doing to do this for macros which have been used for years and would break code but it should be done for any newly defined macros.
/rant over.
Most of Microsoft's new code is Unicode-only (for example, there's no TaskDialogA and TaskDialogW, just TaskDialog), so at least there's no new macros.

And unfortunately, namespaces are out of the question, since Win32 is a C API. Of course, they could've gone with something like GTK's naming convention which is a pretty good compromise if you ask me, but it's a bit late for regrets now :)

Share this post


Link to post
Share on other sites
You could compile your platform-specific(read:windows) code separately and link it, this would also abstract it so that you can make your code multi-platform. You'd just have a link error on each system until you make you new platform lib for each platform.

Share this post


Link to post
Share on other sites
Quote:
Original post by magic_man
Take std::max and windows max macro for an example
This particular thing can be turned off by defining NOMINMAX (which I've defined as default compiler option, so it works on all files in all projects).

But you're of course absolutely right, it's super intrusive and annoying, especially since it's not only about min/max and CreateFile, but dozens of other common names that you might incidentially use (GetMessage, CreateFont, DrawText, anyone?).

The good news is that if you consistenly include windows.h everywhere, then even though it screws up your names, it screws them up everywhere in the same way, so your code will usually still work.

Share this post


Link to post
Share on other sites
magic_man    54
Quote:
Original post by samoth
Quote:
Original post by magic_man
Take std::max and windows max macro for an example
This particular thing can be turned off by defining NOMINMAX (which I've defined as default compiler option, so it works on all files in all projects).

Yes I did mention that :)
Although sometimes that is the wrong option to choose.
Say for example you provide template headers which should be included in a users code, forcing the user to use the macro seems just as wrong to me. This is why for this I prefer to wrap it in parenthesis.
For example

T instance_of_max ((std::numeric_limits<T >::max)());



Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this