Re: Microsoft's obfuscated typedefs considered harmful

Keith Marshall <[email protected]> Tue, 28 May 2013 11:49:11 +0100
Newsgroups gmane.comp.gnu.mingw.devel
Organization MinGW Project
Message-ID <[email protected]>
On 27/05/13 21:47, Earnie Boyd wrote:
> I agree that they're a headache but a required one based on the
> Windows API.

I agree that we must keep them typedef'd.  I wasn't suggesting 
otherwise; rather that we take a more cautious approach to *how* they 
are typedef'd.

> So LONG in both 32bit and 64bit Windows is still long.

But how many bits is a 'long'?  C99 says only that it must be at least 
as long as an 'int', but no fewer than 32 bits, while an 'int' shall be 
at least as long as a 'short', which in turn shall be no fewer than 16 
bits.  The point is that these sizes are *minima*, but not explicit.

All I'm suggesting is that, where an explicit size is intended, we may 
prefer a more explicit typedef; e.g.

   #include <stdint.h>
   ...
   typedef uint16_t WORD;
   typedef uint32_t DWORD;
   ...

in preference to the (existing) vague (non-explicit)

   typedef unsigned short WORD;
   typedef unsigned long DWORD;

Aside: BYTE, WORD, and DWORD are all abstracted from Intel assembly 
language, where they all specify explicit bit lengths, (8, 16, and 32 
bits respectively); I note that Microsoft appear to have neglected to 
derive any QWORD (64 bits) typedef, from the same source.

> Pointers are 64bit on the other hand.

Yep.  I got a compile time warning related to that; pexports had its own 
private (and incorrect) INT_PTR typedef, which was raising warnings 
about casting between pointers and integers of differing sizes.  Using 
the standard 'intptr_t' in place of that, (and standard 'PRIdPTR' in 
place of its associated INT_PTR_FORMAT), resolved *that* issue.

However, a more serious issue arose at runtime; the use of 'LONG' to 
specify the type of the 'e_lfanew' field in the 'IMAGE_DOS_HEADER' 
struct; since 'LONG' is

   typedef long LONG

and 'long' is 64 bits on my 64-bit Debian box, the compiler interpreted 
this as a 64-bit 'e_lfanew' field, (which is wrong -- it *must* be an 
*explicit* 32-bit field), and the application blew up with a segment 
violation fault at runtime, as soon as it tried to parse the DLL image 
content, as referenced by the improperly sized e_lfanew offset value.

In summary: I'm not suggesting that we drop support for these Microsoft 
obfuscated typedefs; rather, we have an opportunity to engineer them 
better, (perhaps even better than Microsoft do themselves), and that we 
should maybe consider doing so.

-- 
Regards,
Keith.

------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service 
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may