19

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.

2

12 Answers 12

7

Use this file: include <IntSafe.h>

Sign up to request clarification or add additional context in comments.

Comments

6

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.

2 Comments

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.
Isn't uint32_t portable speak for unsigned 32 bit entity? Ack, call me thread necro... Why did this pop up as a new questuin? :(
5

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

2 Comments

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.
That's not a good answer, because windows.h declares a lot of macros that polute your namespace and may redefine your code. It's ok for a c/cpp file, but not for a header file.
5

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.

Comments

4

How about - #include <minwindef.h>?

4 Comments

Have you tried this? (That is, successfully compiled a short program that #includes this and contains, e.g., sizeof(DWORD).) Googling suggests that it #defines a max macro, which is annoying but not a dealbreaker if it can be turned off!
@j_random_hacker: just define NOMINMAX. IMO, every project should by default define NOMINMAX and WIN32_LEAN_AND_MEAN unless you specifically need those features.
@VioletGiraffe: Thanks, it sounds like NOMINMAX turns off the max name pollution. But max was just something I happened to come across, and maybe there are also other surprises defined somewhere inside minwindef.h, which require their own NOTHIS and NOTHAT #defines to be turned off. (Even groveling through the header files isn't a complete solution, since they may change across Windows versions...) I was trying to create an unopinionated library, hence my desire not to specify (or require the absence of) WIN32_LEAN_AND_MEAN.
@j_random_hacker: fair point. Either way, it turned out that including minwindef.h is problematic, it probably isn't meant to be be included by users, it's an internal Windows SDK header. IntSafe.h does work, that's probably the best option.
2

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.

1 Comment

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!
2

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.

1 Comment

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

Is there a <wtypes.h> where you're at? Because in it, I see:

#ifndef _DWORD_DEFINED
#define _DWORD_DEFINED
typedef unsigned long DWORD;

#endif // !_DWORD_DEFINED

This file is located under "...\VC98\INCLUDE" here.. which is for VC6 so I'd figured it'll be in later versions.

I was after the same thing as the OP and solved it by including the said header.

2 Comments

Interesting! That particular typedef seems to be wrapped in an #ifdef !defined(_WIN32) && !defined(_MPPC_), which is commented as "The following code is for Win16 only". So I'm surprised that it works for you...?
Hmm.. Quick testing showed that _WIN32 is indeed defined but _MPPC_ isn't.. I couldn't find any useful information about this macro so I have no idea what it is.. Portability may be an issue and ymmv, but it works here despite that comment.. I also noticed the line following that comment is another level of wrapping that goes #ifndef WINAPI with the comment If not included with 3.1 headers..., but WINAPI isn't defined here unless <windows.h> is included.
1

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.

1 Comment

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.
1

Just do typedef unsigned long DWORD; the best solution it imports literally nothing and gives you what you want.

Or even better, do this in a way that is compatible with the Windows header files:

#ifndef _DWORD_DEFINED
#define _DWORD_DEFINED
typedef unsigned long DWORD;
#endif

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
Thanks, but this is roughly the same as this answer, and seems to suffer from the same issues I identified in comments on this one.
0

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.

2 Comments

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

According to the documentation, the official declaration is in <IntSafe.h> or <windef.h>. So this is what’s likely to be supported in the future. These definitions are actually different. In the Windows 11 SDK in 2025, <windef.h> (12K, brings in one other small header) is a much smaller file than <IntSafe.h> (157K, brings in others totalling 60K, several inline function definitions).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.