Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!zodiac!anders@penguin From: anders@penguin (Anders Wallgren) Newsgroups: comp.sys.mac.programmer Subject: Re: MPW compiler bugs (was: interface war) Message-ID: <10936@zodiac.ADS.COM> Date: 17 Feb 90 21:45:04 GMT References: <1990Feb14.004350.14475@oracle.com> <10898@zodiac.ADS.COM> <34412@cci632.UUCP> Sender: news@zodiac.ADS.COM Reply-To: anders@penguin (Anders Wallgren) Organization: Verity Lines: 66 In-reply-to: ph@cci632.UUCP (Pete Hoch) The MPW C compiler optimizes the size of enums depending on what values they take on - if it only has ten values, all of which are less than the maximum value that a data size can hold, then it will make the enum that size. There is no way to turn this off. When CFront compiles your code, it makes all your enums int's, irregardless of what values they hold. Apparently Apple wanted it to optimize enums like their C compiler does, because there is a flag to CFront (-z6, I think) to tell it to NOT optimize enum, but this is in fact what it does all the time. This causes BIG PROBLEMS. For example, if you have a struct with a member that is an enum, and then try to write code in C _and_ C++ that know about this struct, they won't agree on the size of it, and will overwrite each other. Of course there is no warning from either compiler, since they both think they know what they are doing, and no warning from the linker since you're just passing pointers to structs, and not the structs themselves. The following three-file test program will demonstrate this pretty clearly: test.h ------ enum type { type1, type2, type3 }; typedef struct foo { enum type t; short s; long l; } FOO; int kernel(FOO *f); test.c ------ #include "test.h" int kernel(f) FOO *f; { int i = sizeof(FOO); f->t = type2; f->s = 0x0101; f->l = 0x69696969; return i; } test.cp ------- #include extern "C" { #include "test.h" } main(void) { char c[256]; FOO f; char d[256]; int i = sizeof(f); int j = kernel(&f); printf("sizeof foo (c++): %d\n", i); printf("sizeof foo (c): %d\n", j); printf("foo.t (2): %d, foo.s (x0101): %x, foo.l (x69696969): %x\n", f.t, f.s, f.l); }