Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 10, 2006 Top-Down Structs | ||||
---|---|---|---|---|
| ||||
After using some Win32 declarations, wich are obviously not part of "std.c.windows.windows", I have noticed that a resulting program crashes with "Error: Win32 Exception" . This happens if the main structure ("INPUT_RECORD") is declared before the other structures contained in the main structure. The problem will not arise if sub-structs [B] are declared earlier than the main struct [A]. Before that incident I was convinced that the D compiler would handle "top-down" declarations correctly. ----- "Problematic" declaration sequence: ----- // INPUT_RECORD [A] struct INPUT_RECORD { WORD EventType; union { KEY_EVENT_RECORD KeyEvent; MOUSE_EVENT_RECORD MouseEvent; WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; MENU_EVENT_RECORD MenuEvent; FOCUS_EVENT_RECORD FocusEvent; } } // Structs contained in INPUT_RECORD [B] struct KEY_EVENT_RECORD { BOOL bKeyDown; WORD wRepeatCount; WORD wVirtualKeyCode; WORD wVirtualScanCode; union { WCHAR UnicodeChar; CHAR AsciiChar; } DWORD dwControlKeyState; } struct MOUSE_EVENT_RECORD { COORD dwMousePosition; DWORD dwButtonState; DWORD dwControlKeyState; DWORD dwEventFlags; } struct WINDOW_BUFFER_SIZE_RECORD { COORD dwSize; } struct MENU_EVENT_RECORD { UINT dwCommandId; } struct FOCUS_EVENT_RECORD { BOOL bSetFocus; } |
March 10, 2006 Re: Top-Down Structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bob W | In article <duropj$o85$1@digitaldaemon.com>, Bob W says... > > >After using some Win32 declarations, wich are >obviously not part of "std.c.windows.windows", >I have noticed that a resulting program crashes with > > "Error: Win32 Exception" . > >This happens if the main structure ("INPUT_RECORD") >is declared before the other structures contained in >the main structure. The problem will not arise if >sub-structs [B] are declared earlier than the main >struct [A]. > >Before that incident I was convinced that the >D compiler would handle "top-down" declarations >correctly. > > > >----- "Problematic" declaration sequence: ----- > > >// INPUT_RECORD [A] > >struct INPUT_RECORD { > WORD EventType; > union { > KEY_EVENT_RECORD KeyEvent; > MOUSE_EVENT_RECORD MouseEvent; > WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; > MENU_EVENT_RECORD MenuEvent; > FOCUS_EVENT_RECORD FocusEvent; >} } > > >// Structs contained in INPUT_RECORD [B] > >struct KEY_EVENT_RECORD { > BOOL bKeyDown; > WORD wRepeatCount; > WORD wVirtualKeyCode; > WORD wVirtualScanCode; > union { WCHAR UnicodeChar; CHAR AsciiChar; } > DWORD dwControlKeyState; >} > >struct MOUSE_EVENT_RECORD { > COORD dwMousePosition; > DWORD dwButtonState; > DWORD dwControlKeyState; > DWORD dwEventFlags; >} > >struct WINDOW_BUFFER_SIZE_RECORD { COORD dwSize; } >struct MENU_EVENT_RECORD { UINT dwCommandId; } >struct FOCUS_EVENT_RECORD { BOOL bSetFocus; } > > > align(1) ? |
March 10, 2006 Re: Top-Down Structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to AgentOrange | "AgentOrange" <AgentOrange_member@pathlink.com> wrote in message news:dusnj5$2bh1$1@digitaldaemon.com... > > align(1) ? > Nope. |
March 11, 2006 Re: Top-Down Structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bob W | Bob W wrote:
> After using some Win32 declarations, wich are
> obviously not part of "std.c.windows.windows",
> I have noticed that a resulting program crashes with
>
> "Error: Win32 Exception" .
>
> This happens if the main structure ("INPUT_RECORD")
> is declared before the other structures contained in
> the main structure. The problem will not arise if
> sub-structs [B] are declared earlier than the main
> struct [A].
>
> Before that incident I was convinced that the
> D compiler would handle "top-down" declarations
> correctly.
>
>
>
> ----- "Problematic" declaration sequence: -----
>
>
> // INPUT_RECORD [A]
>
> struct INPUT_RECORD {
> WORD EventType;
> union {
> KEY_EVENT_RECORD KeyEvent;
> MOUSE_EVENT_RECORD MouseEvent;
> WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
> MENU_EVENT_RECORD MenuEvent;
> FOCUS_EVENT_RECORD FocusEvent;
> } }
>
>
> // Structs contained in INPUT_RECORD [B]
>
> struct KEY_EVENT_RECORD {
> BOOL bKeyDown;
> WORD wRepeatCount;
> WORD wVirtualKeyCode;
> WORD wVirtualScanCode;
> union { WCHAR UnicodeChar; CHAR AsciiChar; }
> DWORD dwControlKeyState;
> }
>
> struct MOUSE_EVENT_RECORD {
> COORD dwMousePosition;
> DWORD dwButtonState;
> DWORD dwControlKeyState;
> DWORD dwEventFlags;
> }
>
> struct WINDOW_BUFFER_SIZE_RECORD { COORD dwSize; }
> struct MENU_EVENT_RECORD { UINT dwCommandId; }
> struct FOCUS_EVENT_RECORD { BOOL bSetFocus; }
>
>
>
Couldn't repro on my Windows XP machine. Runs without throwing exceptions here.
|
March 12, 2006 Re: Top-Down Structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | "John C" <johnch_atms@hotmail.com> wrote in message news:duuj4n$2ui9$1@digitaldaemon.com... > Couldn't repro on my Windows XP machine. Runs without throwing exceptions here. It all depends what you were doing with the structs. Just declaring them won't cause any trouble. In my case I was calling the Win32 functions PeekConsoleInputA() and/or ReadConsoleInputA(), which was sufficient to upset Win XP. Both functions expect a pointer to an INPUT_RECORD structure. |
March 12, 2006 Re: Top-Down Structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | I just wanted to add this info: Check INPUT_RECORD.sizeof if it is declared before and after its related sub-structs. In the first case the size of INPUT_RECORD will be 4, otherwise the size is 20. |
March 12, 2006 Re: Top-Down Structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bob W | On Sun, 12 Mar 2006 02:02:48 +0100, Bob W <nospam@aol.com> wrote:
> I just wanted to add this info:
>
> Check INPUT_RECORD.sizeof if it is declared before
> and after its related sub-structs. In the first case
> the size of INPUT_RECORD will be 4, otherwise the
> size is 20.
Interestingly naming the union fixes the problem. eg.
struct INPUT_RECORD {
WORD EventType;
union bob {
KEY_EVENT_RECORD KeyEvent;
MOUSE_EVENT_RECORD MouseEvent;
WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
MENU_EVENT_RECORD MenuEvent;
FOCUS_EVENT_RECORD FocusEvent;
}
bob a;
}
(rest of wrong declaration order as given by OP)
results in an INPUT_RECORD.sizeof of 20. I think the bug lies in the handling of anonymous unions.
Regan
|
March 12, 2006 Re: Top-Down Structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Here is the code I used to test this, to save someone else the trouble. Regan ----------- import std.c.windows.windows; import std.stdio; // INPUT_RECORD [A] struct INPUT_RECORD { WORD EventType; union bob { KEY_EVENT_RECORD KeyEvent; MOUSE_EVENT_RECORD MouseEvent; WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; MENU_EVENT_RECORD MenuEvent; FOCUS_EVENT_RECORD FocusEvent; } bob a; } alias INPUT_RECORD* PINPUT_RECORD; // Structs contained in INPUT_RECORD [B] struct KEY_EVENT_RECORD { BOOL bKeyDown; WORD wRepeatCount; WORD wVirtualKeyCode; WORD wVirtualScanCode; union { WCHAR UnicodeChar; CHAR AsciiChar; } DWORD dwControlKeyState; } struct MOUSE_EVENT_RECORD { COORD dwMousePosition; DWORD dwButtonState; DWORD dwControlKeyState; DWORD dwEventFlags; } struct COORD { SHORT X; SHORT Y; } struct WINDOW_BUFFER_SIZE_RECORD { COORD dwSize; } struct MENU_EVENT_RECORD { UINT dwCommandId; } struct FOCUS_EVENT_RECORD { BOOL bSetFocus; } extern(Windows) { BOOL ReadConsoleInputA(HANDLE hConsoleInput, PINPUT_RECORD lpBuffer, DWORD nLength, LPDWORD lpNumberOfEventsRead); BOOL ReadConsoleInputW(HANDLE hConsoleInput, PINPUT_RECORD lpBuffer, DWORD nLength, LPDWORD lpNumberOfEventsRead); HANDLE GetStdHandle(DWORD nStdHandle); DWORD STD_INPUT_HANDLE = cast(DWORD)-10; DWORD STD_OUTPUT_HANDLE = cast(DWORD)-11; DWORD STD_ERROR_HANDLE = cast(DWORD)-12; WORD KEY_EVENT = 0x0001; // Event contains key event record WORD MOUSE_EVENT = 0x0002; // Event contains mouse event record WORD WINDOW_BUFFER_SIZE_EVENT = 0x0004; // Event contains window change event record WORD MENU_EVENT = 0x0008; // Event contains menu event record WORD FOCUS_EVENT = 0x0010; // event contains focus change } char[][WORD] types; static this() { types[KEY_EVENT] = "Key Event"; types[MOUSE_EVENT] = "Mouse Event"; types[WINDOW_BUFFER_SIZE_EVENT] = "Window Buffer Size Event"; types[MENU_EVENT] = "Menu Event"; types[FOCUS_EVENT] = "Focus Event"; } void main() { HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); INPUT_RECORD rec; DWORD rd; writefln("INPUT_RECORD.sizeof = ",INPUT_RECORD.sizeof); if (ReadConsoleInputA(hIn,&rec,cast(DWORD)1,&rd) == 0) { writefln("ReadConsoleInputA failed"); return ; } writefln(rd," records read:"); writefln("Type: ",types[rec.EventType]); } |
March 12, 2006 Re: Top-Down Structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | "Regan Heath" <regan@netwin.co.nz> wrote in message news:ops6amc90r23k2f5@nrage.netwin.co.nz... > On Sun, 12 Mar 2006 02:02:48 +0100, Bob W <nospam@aol.com> wrote: >> I just wanted to add this info: >> >> Check INPUT_RECORD.sizeof if it is declared before >> and after its related sub-structs. In the first case >> the size of INPUT_RECORD will be 4, otherwise the >> size is 20. > > Interestingly naming the union fixes the problem. eg. > > struct INPUT_RECORD { > WORD EventType; > union bob { > KEY_EVENT_RECORD KeyEvent; > MOUSE_EVENT_RECORD MouseEvent; > WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; > MENU_EVENT_RECORD MenuEvent; > FOCUS_EVENT_RECORD FocusEvent; > } > bob a; > } > > (rest of wrong declaration order as given by OP) > > results in an INPUT_RECORD.sizeof of 20. I think the bug lies in the handling of anonymous unions. > > Regan Good job! Looks like a usable workaround. But in the long term I would rather like to see the D compiler to stick to its promises: "anonymous structs/unions are allowed as members of other structs/unions" |
March 12, 2006 Re: Top-Down Structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bob W | On Sun, 12 Mar 2006, Bob W wrote:
> "Regan Heath" <regan@netwin.co.nz> wrote in message news:ops6amc90r23k2f5@nrage.netwin.co.nz...
> > On Sun, 12 Mar 2006 02:02:48 +0100, Bob W <nospam@aol.com> wrote:
> >> I just wanted to add this info:
> >>
> >> Check INPUT_RECORD.sizeof if it is declared before
> >> and after its related sub-structs. In the first case
> >> the size of INPUT_RECORD will be 4, otherwise the
> >> size is 20.
> >
> > Interestingly naming the union fixes the problem. eg.
> >
> > struct INPUT_RECORD {
> > WORD EventType;
> > union bob {
> > KEY_EVENT_RECORD KeyEvent;
> > MOUSE_EVENT_RECORD MouseEvent;
> > WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
> > MENU_EVENT_RECORD MenuEvent;
> > FOCUS_EVENT_RECORD FocusEvent;
> > }
> > bob a;
> > }
> >
> > (rest of wrong declaration order as given by OP)
> >
> > results in an INPUT_RECORD.sizeof of 20. I think the bug lies in the handling of anonymous unions.
> >
> > Regan
>
> Good job! Looks like a usable workaround. But in the long term I would rather like to see the D compiler to stick to its promises:
>
> "anonymous structs/unions are allowed as members of other structs/unions"
Would one of you finish minimizing the test case and file it in bugzilla?
Thanks,
Brad
|
Copyright © 1999-2021 by the D Language Foundation