Win32 GetMessage: The BOOL That Returns Nonzero, Zero, or -1
Why is this Microsoft meme funny?
Level 1: The Light Switch With Three Positions
Imagine a light switch that the manual swears is a simple on/off switch — but it actually has three positions: on, off, and secretly broken. The tricky part is that "secretly broken" looks exactly like "on," so your lights stay lit while the wiring quietly catches fire. The instruction book even admits it: "Because the switch can be on, off, or broken, please don't use it the normal way." Everyone laughs because the company could never fix the switch — too many houses already built around it — so instead they just kept making the warning in the manual longer and longer.
Level 2: Reading the Crime Scene
GetMessage— the Win32 function a desktop app calls in a loop to pull keyboard, mouse, and system messages from its queue. Every classic Windows program is, at its core,while (GetMessage(...)) { dispatch }.BOOL— in Windows headers, just an alias forint. It can hold any integer; "TRUE/FALSE" is a social convention, not an enforced rule. Modern languages'booltypes exist precisely to prevent this image from happening.WM_QUIT— the special message meaning "the app should exit"; it's the legitimate zero-return that ends the loop.GetLastError— Win32's pattern for error details: the function returns a failure sentinel, and you call this to learn why. Forget to check the sentinel, and you never call it.- Truthiness — in C, any nonzero value is "true" in a condition. That's why
-1(error) and1(success) look identical towhile (...)— the bug in one sentence.
The junior-dev rite of passage encoded here: discovering that documentation contains the sentence "avoid code like this" describing exactly the code you just wrote. Old APIs are full of these museum-quality warning plaques; reading the Return Value section before the Parameters section is a habit that separates the scarred from the soon-to-be-scarred.
Level 3: A Boolean Walks Into Three Bars
The screenshot needs no edits, no caption, no impact font — it's just Microsoft's own documentation for GetMessage, the beating heart of every Win32 message loop, with two phrases highlighted like evidence in a deposition. First: Type: BOOL. Then, after the docs calmly enumerate the outcomes —
If the function retrieves a message other than WM_QUIT, the return value is nonzero. If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1.
— comes the sentence that made this a meme:
Because the return value can be nonzero, zero, or -1, avoid code like this:
A boolean with three meaningful states, documented with the serenity of a weather report. The comedy is not that Microsoft made a mistake; it's that the mistake is load-bearing, eternal, and politely annotated.
The archaeology here is genuinely instructive. Win32's BOOL is not a boolean type at all — it's a typedef int from the era of Hungarian notation and C compilers with no real bool. When GetMessage was designed (Windows message loops date to the 16-bit 1980s), returning the message-retrieval status as an int was natural, and the error case -1 was bolted on later — after the function's signature was already frozen into the most binding contract in software: Win32 backwards compatibility. Microsoft famously preserves bugs because applications depend on them; changing GetMessage to return a sane enum would break decades of shipped binaries. So instead, the type stays BOOL, the third value stays -1, and the documentation grows a warning label.
And the trap is exquisite, because the natural idiom — the one in every tutorial since Petzold —
while (GetMessage(&msg, NULL, 0, 0)) // looks correct, is a landmine
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
treats the result as truthy. But -1 is nonzero, hence true, so on error (an invalid hWnd, a bad lpMsg pointer) this loop doesn't exit — it spins forever processing garbage, pegging a core while dispatching uninitialized message structs. The correct form is the awkward while ((bRet = GetMessage(...)) != 0) { if (bRet == -1) ... }, which nobody writes until the bug bites them. The docs page literally exists to plead with developers not to use the obvious idiom that the function's own type signature invites. That's the deepest joke: the API's type is an attractive nuisance, and the documentation is the fence built around it forty years too late.
This is the canonical exhibit in every API-design talk about why return types are contracts and why in-band error signaling (errors smuggled inside the value's domain) eventually betrays you — the same disease as strtol returning 0, PHP's strpos returning false-but-sometimes-0, and JavaScript's indexOf returning -1. The industry keeps relearning it because the convenient signature always ships first.
Description
A dark-themed screenshot of Microsoft's Win32 API documentation for the GetMessage function's 'Return value' section. It states the type is 'BOOL' (highlighted), then explains: if the function retrieves a message other than WM_QUIT, the return value is nonzero; if it retrieves the WM_QUIT message, the return value is zero; if there is an error, the return value is -1 - for example if hWnd is an invalid window handle or lpMsg is an invalid pointer, with GetLastError for extended info. The final line, with 'the return value can be nonzero, zero, or -1' highlighted, reads 'Because the return value can be nonzero, zero, or -1, avoid code like this:'. The humor is the self-evident absurdity of a 'boolean' type with three meaningful states, a legendary Win32 API design wart that has caused countless message-loop bugs from 'while (GetMessage(...))' patterns
Comments
13Comment deleted
Win32's BOOL has three values because backwards compatibility means never having to say your type system is sorry
technically valid Comment deleted
Winapi vibes Comment deleted
WomenAPI vibes, where "yes" may as well have a negative meaning, and "no" may be an acknowledgement ("no problem"). 💅 Comment deleted
Yeah! I was right! https://github.com/microsoft/CsWin32/issues/362 Comment deleted
but -1 IS nonzero Comment deleted
Shhhhh don't break it down to them. Comment deleted
zoomers discovered winapi BOOL is not boolean typedef int BOOL; Comment deleted
>tristate Phineas and ferb ahh programming Comment deleted
What Comment deleted
whar. Comment deleted
I find it stupid how we have a 1 bit type when all machines are 8 bit addressible Comment deleted
bool is useful as an abstraction, not as a fixed-width type Comment deleted