digitalmars.D.bugs - Top-Down Structs
- Bob W (41/41) Mar 10 2006 After using some Win32 declarations, wich are
- AgentOrange (2/43) Mar 10 2006 align(1) ?
- Bob W (3/4) Mar 10 2006 Nope.
- John C (3/61) Mar 11 2006 Couldn't repro on my Windows XP machine. Runs without throwing
- Bob W (9/11) Mar 11 2006 It all depends what you were doing with the structs.
- Bob W (5/5) Mar 11 2006 I just wanted to add this info:
- Regan Heath (17/22) Mar 12 2006 Interestingly naming the union fixes the problem. eg.
- Regan Heath (82/82) Mar 12 2006 Here is the code I used to test this, to save someone else the trouble.
- Bob W (5/28) Mar 12 2006 Good job! Looks like a usable workaround. But in the long term I would
- Brad Roberts (4/39) Mar 12 2006 Would one of you finish minimizing the test case and file it in bugzilla...
- Regan Heath (4/5) Mar 12 2006 Done.
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; }
Mar 10 2006
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) ?
Mar 10 2006
"AgentOrange" <AgentOrange_member pathlink.com> wrote in message news:dusnj5$2bh1$1 digitaldaemon.com...align(1) ?Nope.
Mar 10 2006
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.
Mar 11 2006
"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.
Mar 11 2006
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.
Mar 11 2006
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
Mar 12 2006
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]);
}
Mar 12 2006
"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: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"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
Mar 12 2006
On Sun, 12 Mar 2006, Bob W wrote:"Regan Heath" <regan netwin.co.nz> wrote in message news:ops6amc90r23k2f5 nrage.netwin.co.nz...Would one of you finish minimizing the test case and file it in bugzilla? Thanks, BradOn Sun, 12 Mar 2006 02:02:48 +0100, Bob W <nospam aol.com> wrote: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"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
Mar 12 2006
On Sun, 12 Mar 2006 10:49:36 -0800, Brad Roberts <braddr puremagic.com> wrote:Would one of you finish minimizing the test case and file it in bugzilla?Done. Regan
Mar 12 2006









"Bob W" <nospam aol.com> 