tags:

views:

658

answers:

7

I have a small header file of my own which declares a couple of functions, one of which has a return type of DWORD. I'm reluctant to drag in windows.h just to get the official definition of this type since that file is huge, and my header will be used in a number of source modules that don't otherwise need it.

Of course, in practice I know that DWORD is just unsigned int, but I'd prefer the more hygienic approach of including an official header file if possible.

On this page it says that DWORD is defined in windef.h, but unfortunately including just this small file directly leads to compilation errors -- apparently it expects to be included by other headers. (Also, the fact that my file is a header file also means I can't just declare WIN32_LEAN_AND_MEAN, since the source file that #includes my file might need this to be left undefined.)

Any ideas? I know it's not the end of the world -- I can just continue to #include <windows.h> -- but thought someone might have a better idea!

[EDIT] Thanks for your responses. To those who suggested using a different type, let me explain why that's not desirable in this case: I've set up different, platform-specific versions of the two functions in different source files, and ask the CMake configuration to detect the current platform and choose which one to build. On Windows, my functions look like:

typedef DWORD TimePoint;
TimePoint GetTimeNow(void);
double TimeDifference(TimePoint start, TimePoint end);

The Windows version of GetTimeNow() just calls the Windows API timeGetTime(), which has return type DWORD, and so it must have the same return type. (On other platforms, TimePoint will have a different type, e.g. struct timeval on UNIXy platforms.) In effect, values of type TimePoint are opaque, and the only thing you can do with them is pass two of them to TimeDifference() to measure the elapsed time between them in seconds. This enables cross-platform development. Unfortunately it still means that client code has to know the concrete type of TimePoint.

+3  A: 

Include Windows.h and use precompiled headers. Btw, you can define WIN32_LEAN_AND_MEAN and then undef it later!

Aram Hăvărneanu
Precompiled headers is a good idea, but I'm worried that including windows.h with WIN32_LEAN_AND_MEAN defined before later including it without might cause the latter #include to be ignored due to #include guards.
j_random_hacker
+2  A: 

I'd say to just define it yourself. That way, it's more platform-independent (of course, I don't know if the rest of the code requires Windows). If you don't want to do that, use precompiled headers.

Javier Badia
Precompiled headers is a good idea, but in this case it's not more platform-independent to define it myself -- please see my edits in the original question. Thanks!
j_random_hacker
A: 

Why don't you instead define the function to return int? This is a highly portable type and completely divorces your code from the evil empireMicrosoft.

wallyk
How is replacing "the evil empire" with "Microsoft" relevant to SO in any way?
Tom
I've clarified my question to explain why in this case, I need to return Windows' idea of a `DWORD`. Thanks anyway :)
j_random_hacker
A: 

Don't use a DWORD. I have seen too much Windows code that have been ported to other platforms later. Those DWORDs become a real problem when everybody has their own definition for it. I don't think there are any good reasons to use windows specific types in interfaces.

Even if your code will never be ported to any other platform, I still think code should use the native types or your own types (e.g., MyInt32, MyUInt64, etc), but nothing from windows.h.

Tuomas Pelkonen
I've clarified my question to explain why in this case, I need to return Windows' idea of a `DWORD`. Thanks anyway :)
j_random_hacker
+2  A: 

I believe you used to be able to include winbase.h, but that doesn't seem to be the case anymore. All of the sources I've seen recommend windows.h, with the option of WIN32_LEAN_AND_MEAN. As you've indicated, the latter optimization doesn't help you.

You could do something like this.

#ifndef _WINDEF_
typedef unsigned long DWORD;
#endif

Not clean, but efficient. This typedef isn't likely to ever change.

Todd
winbase.h was a good idea, thanks for trying.
j_random_hacker
+1  A: 

A DWORD is always going to be a 32-bit unsigned int, so it doesn't really matter whether you use DWORD or unsigned long or uint32_t. If all three types refer to a 32-bit unsigned int, the compiler is going to consider them equivalent.

Since this is part of the platform-specific files, I don't think you need to worry about portability so much. Heck, dig into the headers to find the native type of a DWORD and just put that typedef in your header. C compilers accept duplicate typedefs as long as they have the same underlying type.

tomlogic
Actually that's not a bad idea: Windows is constrained from ever changing the type of `DWORD` for compatibility reasons, so I might as well dig up that type and use it directly.
j_random_hacker
+1  A: 

If you're worried that when your cross-platform program runs on Windows it will load too many Windows DLLs just because your source code had #include <windows.h>, I think you're worrying too much. Even Notepad has to load half of the known universe, and it has been known to load and execute on occasion.

If you're worried that when other developers use Windows your cross-platform .h file will put a ton of namespace pollution in their compilation environments, I think you're worrying too much. 99.999% of Windows projects already did an #include <windows.h> before they got to your .h file.

Windows programmer
No DLLs will be loaded because I include a header file, so that's not what I'm worried about. I just wanted a lighter-weight header to reduce compilation time if possible. I'll try turning on precompiled headers instead, hopefully there won't be any negative interactions with the CMake build system.
j_random_hacker