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