The following code (part of a simple GUI running on a 251 platform with an LCD) attempts to pass a struct which is a member of another struct on the stack. A pointer to the container struct is dereferenced using the '->' operator. The call to DrawRect below is supposed to pass certain members of the WindowContext struct, namely two ScreenPoint structs and a byte. Instead the compiler appears to be incorrectly passing the entire WindowContext struct on the stack, and therefore the DrawRect routine that receives the faulty parameters becomes hopelessly confused.
What is going on here? (Using C251 4.00) Thanks...
struct ScreenPoint { unsigned char x; unsigned char y; }; typedef struct ScreenPoint SCREENPT; typedef struct ScreenPoint SCREENSZ; struct WindowContext { SCREENPT OrgPt; SCREENSZ TotalSz; unsigned char BorderColor; /*Etc...*/ }; typedef struct WindowContext *WinPtr; void DrawRect(SCREENPT Org, SCREENSZ Sz, unsigned char Color) reentrant; TestFunction(WinPtr pWin) reentrant { DrawRect(pWin->OrgPt, pWin->TotalSz, pWin->BorderColor); }
Hard to say without further information... The struct passing is ok, does it look the same on your side ?
OK, apologies, I was not transcribing the test code accurately.
Please try it with the following modification. The WindowContext is passed as a void pointer (because we don't want TestFunction's caller to have access to the struct declaration). Apparently using the void pointer is what leads to the problem.
You should now see a loop among the PUSH instructions where it is loading the whole pWin struct onto the stack.
void TestFunction(void* p) reentrant { WinPtr pWin = (WinPtr)p; DrawRect2(pWin->OrgPt, pWin->TotalSz, pWin->BorderColor); }
Well, after bouncing this off you, I seem to have managed to track down the problem myself.
If I replace the line...
WinPtr pWin = (WinPtr)p;
...with this...
WinPtr pWin = p;
...the problem is gone. Evidently it was displeased by the explicit cast we were doing there, which was not really needed anyway.