Path: utzoo!mnetor!uunet!husc6!cmcl2!brl-adm!adm!PEPRBV%CFAAMP.BITNET@MITVMA.MIT.EDU From: PEPRBV%CFAAMP.BITNET@MITVMA.MIT.EDU (Bob Babcock) Newsgroups: comp.lang.c Subject: huge problem Message-ID: <12575@brl-adm.ARPA> Date: 23 Mar 88 00:55:03 GMT Sender: news@brl-adm.ARPA Lines: 93 I seem to have found a problem with huge pointers in Turbo C 1.5. The following program can be compiled with either Turbo C or MSC 5.0 to demonstrate the problem. Note that both Borland and especially Microsoft are a little vague about the exact properties of huge pointers, and since huge is an extension of ANSI standard, there's no place beyond their manuals to look. By the way, do people at Borland (and Microsoft) see these lists? I'll probably file an official bug report eventually, but so far I haven't even bothered to mail in my registration cards. ---------- #include #ifdef __TURBOC__ #include #define ALLOCATE(x,y) farcalloc(x,y) #else #include #define ALLOCATE(x,y) halloc(x,y) #endif /* Compile this with the large model flag under Turbo C 1.5 to demonstrate an apparent problem with huge pointers to structures. MSC 5.0 seems to get it right. */ struct record { unsigned char string[28]; unsigned long stuff; }; void main(void) { struct record huge *xx; struct record *aa,*bb,*cc; xx=(struct record huge *)ALLOCATE(3001L, (unsigned long)sizeof(struct record)); #ifdef __TURBOC__ printf("Output when compiled with Turbo C 1.5, large model\n"); #else printf("Output when compiled with MSC 5.0, large model\n"); #endif if(xx == 0) printf("Warning: memory allocation failed\n"); printf("size of structure record is %d\n", sizeof(struct record)); /* Turbo C claims that huge pointers are always normalized, yet the first printf below prints the same segment for all 3 pointers, which is just plain wrong for xx[3000].string since it is more than 64K away from xx[0].string. More subtle is the problem with xx[2047].string which gets an offset of FFEC: the string crosses a segment boundary, so any use is likely to suffer from segment wrap around. The second printf shows a work-around which gives the right answers, and may be more efficient if multiple references are made to the same structure. Microsoft C 5.0 seems to get this right. The pointers are not normalized, but the starting address returned by halloc is adjusted so that the end of an element is exactly a segment boundary. This is apparently why halloc requires that the element size be a power of 2 for arrays larger than 128K. */ printf("xx[0] - %Fp, xx[2047] - %Fp, xx[3000] - %Fp\n", xx[0].string, xx[2047].string, xx[3000].string); aa=(struct record *)xx; bb=(struct record *)(xx+2047); cc=(struct record *)(xx+3000); printf("aa - %Fp, bb - %Fp, cc - %Fp\n", aa->string, bb->string, cc->string); return; } Output when compiled with Turbo C 1.5, large model size of structure record is 32 xx[0] - 5767:000C, xx[2047] - 5767:FFEC, xx[3000] - 5767:770C aa - 5767:000C, bb - 6765:000C, cc - 6ED7:000C Output when compiled with MSC 5.0, large model size of structure record is 32 xx[0] - 6640:0000, xx[2047] - 6640:FFE0, xx[3000] - 7640:7700 aa - 6640:0000, bb - 6640:FFE0, cc - 7640:7700 [Your segment registers will be different, of course]