syswerda@bbn.com (Gilbert Syswerda) (11/16/90)
/* This program compiles without errors or warnings, using the large memory model. I have several questions. 1. The return type for sizeof() is defined in alloc.h as unsigned. If this is so, how can it be returning such large values? 2. Why is the size of c3 only 2 bytes? 3. Why is the size of b3 only 2 bytes, yet b3.vals 64K bytes? 4. Looking at c4, how can I define a huge class structure? 5. It would be interesting if someone would run this code under 1.01 to see if it does the same thing. Caveat: I am fairly new to both C and C++. However, I do understand Intel's segmented architecture (and expect Borland to understand it too). I made a similar posting a couple months ago, but was pulled away for a while. My apologies to those who attempted to answer this the last time. */ #include <stdio.h> #include <alloc.h> typedef char a1[65535]; typedef char a2[65536]; // This is *exactly* 64K worth of chars typedef char huge a3[65537]; // Compiler complains if not declared huge typedef char huge a4[12345678]; // Ditto class c1 { public: unsigned long l; }; class c2 { public: c1 vals[16383]; }; class c3 { public: c1 vals[16384]; // This is exactly 64K worth of longs }; /* Compiler will not compile the following: it complains that the structure is too large. I don't know how to make it huge. class c4 { public: c1 vals[16384]; // This is 64K bytes char ch; // Plus one more }; */ void main() { long l; // This is used to allow the compiler to do type conversion from // whatever sizeof is returning. c2 b2; c3 b3; char a5[65536]; // 64K worth of chars char huge a6[99999]; // more than 64K printf ("\n\n\n"); printf (" Coreleft: %ld\n", l = coreleft()); printf ("Farcoreleft: %ld\n\n", l = farcoreleft()); printf ("Sizeof a1: %ld\n", l = (sizeof (a1))); printf ("Sizeof a2: %ld\n", l = (sizeof (a2))); printf ("Sizeof a3: %ld\n", l = (sizeof (a3))); printf ("Sizeof a4: %ld\n\n", l = (sizeof (a4))); printf ("Sizeof a5: %ld\n", l = (sizeof (a5))); printf ("Sizeof a6: %ld\n\n", l = (sizeof (a6))); printf ("Sizeof c1: %ld\n\n", l = (sizeof (c1))); printf ("Sizeof c2: %ld\n", l = (sizeof (c2))); printf ("Sizeof c3: %ld\n\n", l = (sizeof (c3))); printf ("Sizeof b2: %ld\n", l = (sizeof (b2))); printf ("Sizeof b3: %ld\n\n", l = (sizeof (b3))); printf ("Sizeof b2.vals: %ld\n", l = (sizeof (b2.vals))); printf ("Sizeof b3.vals: %ld\n", l = (sizeof (b3.vals))); } /* Program output Coreleft: 403504 Farcoreleft: 403504 Sizeof a1: 65535 Sizeof a2: 65536 Sizeof a3: 65537 Sizeof a4: 12345678 Sizeof a5: 65536 Sizeof a6: 99999 Sizeof c1: 4 Sizeof c2: 65532 Sizeof c3: 2 Sizeof b2: 65532 Sizeof b3: 2 Sizeof b2.vals: 65532 Sizeof b3.vals: 65536 */
grimlok@hubcap.clemson.edu (Mike Percy) (11/17/90)
I couldn't get this out by mail, sorry To: syswerda@bbn.com Subject: Re: Borland C++ memory allocation questions Newsgroups: comp.lang.c++ References: <60903@bbn.BBN.COM> In comp.lang.c++ you write: >/* >This program compiles without errors or warnings, using the large >memory model. I have several questions. >1. The return type for sizeof() is defined in alloc.h as unsigned. If > this is so, how can it be returning such large values? To print an unsigned you must use the unsigned format! %u or %lu. >2. Why is the size of c3 only 2 bytes? See below... >3. Why is the size of b3 only 2 bytes, yet b3.vals 64K bytes? See below... >4. Looking at c4, how can I define a huge class structure? >5. It would be interesting if someone would run this code under 1.01 to > see if it does the same thing. I've modified the code to correct some mistakes... #include <stdio.h> #include <alloc.h> typedef char a1[65535]; typedef char a2[65536]; // This is *exactly* 64K worth of chars // 65535 is a long constant 0x0000FFFF, when converted to integer 0xFFFF // 65536 is a long constant 0x00010000, when converted to integer 0x0000 typedef char huge a3[65537]; // Compiler complains if not declared huge typedef char huge a4[12345678]; // Ditto // 65537 is a long constant 0x00010001, when converted to integer 0x0001 // didn't work out 12345678, but lop of high 16 bits and I'm sure you're // left with 24910... // See p 331 (Programming Guide 3.3.3.4 // For a normal array, the type [to hold max. size of array] is // unsigned int, and for huge arrays the type is signed long.) // Note that for a3 and a4, there is no problem with the declaration. // The problem is that sizeof() return size_t which is unsigned int. // Actually there is a problem -- you still don't get the space you ask // for. Have a look at the assembly code. The workings of arrays of // size > 64K is more complicated than I have time to into right now. // The easiest thing to do is to dynamically allocate them farmalloc() // and address them with a huge pointer. class c1 { public: unsigned long l; }; // ok here class c2 { public: c1 vals[16383]; }; // ok here -- index not long, and size < 64K class c3 { public: c1 vals[16384]; // This is exactly 64K worth of longs }; // see above size = 64K = 0x00010000, in unsigned int = 0x0000 /* Compiler will not compile the following: it complains that the structure is too large. I don't know how to make it huge. class c4 { public: c1 vals[16384]; // This is 64K bytes char ch; // Plus one more }; // not sure how to fix this one, will have to think about it // but see above about handling data structures (not just arrays) // larger than 64K */ void main() { long l; // This is used to allow the compiler to do type conversion from // whatever sizeof is returning. // sorry, not quite what you needed to do. c2 b2; c3 b3; char a5[65536]; // 64K worth of chars // See above... char huge a6[99999]; // more than 64K // See above... printf ("\n\n\n"); printf (" Coreleft: %lu\n", coreleft()); // rather than %ld printf ("Farcoreleft: %lu\n\n", farcoreleft()); printf ("Sizeof a1: %u\n", (sizeof (a1))); printf ("Sizeof a2: %u\n", (sizeof (a2))); printf ("Sizeof a3: %u\n", (sizeof (a3))); printf ("Sizeof a4: %u\n\n", (sizeof (a4))); printf ("Sizeof a5: %u\n", (sizeof (a5))); printf ("Sizeof a6: %u\n\n", (sizeof (a6))); printf ("Sizeof c1: %u\n\n", (sizeof (c1))); printf ("Sizeof c2: %u\n", (sizeof (c2))); printf ("Sizeof c3: %u\n\n", (sizeof (c3))); printf ("Sizeof b2: %u\n", (sizeof (b2))); printf ("Sizeof b3: %u\n\n", (sizeof (b3))); printf ("Sizeof b2.vals: %u\n", (sizeof (b2.vals))); printf ("Sizeof b3.vals: %u\n", (sizeof (b3.vals))); } These are the results, which are exactly what is expected... tcc -ml -w message.cpp Turbo C++ Version 1.00 Copyright (c) 1990 Borland International message.cpp: Warning message.cpp 4: Constant is long Warning message.cpp 5: Constant is long Warning message.cpp 7: Constant is long Warning message.cpp 8: Constant is long Warning message.cpp 43: Constant is long in function main Warning message.cpp 44: Constant is long in function main Warning message.cpp 68: 'a6' is declared but never used in function main() Warning message.cpp 68: 'a5' is declared but never used in function main() Warning message.cpp 68: 'b3' is declared but never used in function main() Warning message.cpp 68: 'b2' is declared but never used in function main() Turbo Link Version 3.0 Copyright (c) 1987, 1990 Borland International Available memory 26208 Coreleft: 298768 Farcoreleft: 298768 Sizeof a1: 65535 Sizeof a2: 0 Sizeof a3: 1 Sizeof a4: 24910 Sizeof a5: 0 Sizeof a6: 34463 Sizeof c1: 4 Sizeof c2: 65532 Sizeof c3: 2 Sizeof b2: 65532 Sizeof b3: 2 Sizeof b2.vals: 65532 Sizeof b3.vals: 0
grimlok@hubcap.clemson.edu (Mike Percy) (11/17/90)
grimlok@hubcap.clemson.edu (Mike Percy) writes:
Sorry about that previous post. I made some un-true statements.
My explanations hold true under TC++ in the C mode, but
apparently in C++ mode, sizeof works a little differently, as does
array declarations (can declare bigger arrays in C++ than in C).
Apparently sizeof returns unsigned long when it is used in a binary
operation with a long. It returns unsigned int otherwise.
I've just gotten so used to the TC++ C mode, that my knee jerked when I
saw these (so often seen complained about in C mode).
To the original poster: The Borland documentation is obviously (was
there ever any doubt?) not perfect. I figured this stuff out with the
-S (generate assmbly listing), if you understand the Intel architecture,
you'll be able to spot the problems.
"I don't know about your brain, but mine is really...bossy."
Mike Percy grimlok@hubcap.clemson.edu
ISD, Clemson University mspercy@clemson.BITNET
(803)656-3780 mspercy@clemson.clemson.edu