[comp.lang.c++] Petzold's Windows examples with Zortech 2.1

ted@grebyn.com (Ted Holden) (03/06/91)

 
 
 
 
   Maybe Walter Bright or someone could answer this;  the guys on the tech
line at Zortech couldn't.  In Petzold's book "Programming Windows",
which is pretty much the standard book on the topic, the standard
section of code for setting up a window class (at least in one case) reads:
 
 
     if (!hPrevInstance) 
          {
          zwndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          zwndclass.lpfnWndProc   = WndProc ;
          zwndclass.cbClsExtra    = 0 ;
          zwndclass.cbWndExtra    = 0 ;
          zwndclass.hInstance     = hInstance ;
          zwndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          zwndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          zwndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          zwndclass.lpszMenuName  = NULL ;
          zwndclass.lpszClassName = szAppName ;
 
          RegisterClass (&zwndclass) ;
          }
 
and this won't compile under Zortech 2.1.  The function name WndProc
must be typecast to void, i.e. the 2'nd line
 
 
          zwndclass.lpfnWndProc   = WndProc ;
 
must be changed to
 
          zwndclass.lpfnWndProc   = (void *) WndProc ;
 
and then the whole thing works with Zortech 2.1.  Nothing in windows.h would
seem to suggest such a requirement.  What gives??
 
Ted Holden
HTE
 
 
 
 
 
 

bright@nazgul.UUCP (Walter Bright) (03/14/91)

In article <1991Mar6.130447.16332@grebyn.com> ted@grebyn.com (Ted Holden) writes:
/          zwndclass.lpfnWndProc   = WndProc ;
/must be changed to
/          zwndclass.lpfnWndProc   = (void *) WndProc ;
/and then the whole thing works with Zortech 2.1.  Nothing in windows.h would
/seem to suggest such a requirement.  What gives??

The trouble is that ZTC does ANSI type checking of argument and pointer types.
It seems that a large percentage of windows code (including the SDK sample code)
is written assuming that two types are the same *if they have the same number
of bytes of storage* (!). These problems are usually easilly solved by proto-
typing functions using ANSI C rules, and judicious use of casts. For instance,
there are cases where a long is cast to a 4 byte struct as in:
	func((struct X) y);
where y is a long. This can be converted to ANSI C by:
	func(*(struct X*)&y);
In general, this technique can be used when a type 'paint' is required (a paint
is when you change the type of an object without changing any bits).

We are working on a switch to the compiler to allow it to compile code that is
written under the assumption that size==type, but be aware that using this
feature will make it hard to port code from 16 to 32 bit compilers.
It will also conceal hard-to-find bugs in the code.

As a test of your compiler's type checking, it should fail to compile the
following:

	short *s;
	int *i;
	i = s;		/* type mismatch */

	int *p;
	int **pp;
	pp = p;		/* type mismatch */

	char *c;
	signed char *sc;
	sc = c;		/* type mismatch */

etc.