home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!cs.utexas.edu!ut-emx!jamshid
- From: jamshid@ut-emx.uucp (Jamshid Afshar)
- Newsgroups: comp.lang.c++
- Subject: Re: Borland C++ 3.1 fails to conform to C++ Standard
- Summary: 'huge' is not Standard C++
- Keywords: C++ Standard
- Message-ID: <76636@ut-emx.uucp>
- Date: 27 Jul 92 07:54:29 GMT
- References: <j_ohearn.711991770@dn73>
- Reply-To: jamshid@emx.utexas.edu
- Followup-To: comp.os.msdos.programmer
- Organization: The University of Texas at Austin; Austin, Texas
- Lines: 96
-
- As the crux of the problem is related to a common MS-DOS C/C++
- compiler extension, I have redirected followups to
- comp.os.msdos.programmer.
-
- In article <j_ohearn.711991770@dn73> j_ohearn@dsg4.dse.beckman.com writes:
- >class Vector
- >{
- > double huge *data;
-
- First, there is no Standard C++ yet. Second, I'm sure it will not
- contain the modifier 'huge', so it's not quite valid to claim Borland
- is nonconforming because of a problem related to the use of that keyword.
-
- > public: [...]
- > double& operator()( unsigned long i ) {
- > return data[i - low]; //Line that offends ver 3.1 but compiled without
- > } //error under 3.0
- >};
-
- You declare operator() as returning a reference to a double.
- Depending on which memory model you are compiling under, pointers and
- references are assumed to be either 'near' or 'far' (never 'huge'; not
- even in the huge memory model). 'data' is a 'huge' pointer so you are
- actually returning a 'double huge&' from within operator().
- Therefore, you're assigning a 'double huge&' to either a 'double
- near&' (unsafe conversion) or a 'double far&' (safe, but still a
- conversion). According to the ARM 8.4.3, a non-const reference can
- only be initialized by an object of the exact same type -- no
- conversions are allowed. Earlier C++ rules (which BC++ 3.0 implemented
- with a warning) said that a temporary would be created and the
- reference would be initialized to that. Now only const references can
- create a temporary.
- const double& d2 = 1; // okay, temporary "1.0" generated
- double& d1 = 1; // error, but earlier rules would generate temporary
-
- Of course, how the above ARM rule applies to an MS-DOS extensions like
- 'huge'/'far'/'near' is up to the compiler maker (another good reason
- not to use extensions), but BC++ 3.1's behavior does seem to be
- consistent with the "standard" part of the language.
-
- >Vector::Vector(unsigned long L, unsigned long H)
- >{
- > low = L;
- > high = H;
- > data = new double huge[H - L + 1];
-
- So that's how you get 'new' to allocate over 64K objects! This is
- analogous to farmalloc(). It calls Borland's
- void* operator new(unsigned long);
- instead of
- void operator new(size_t); // size_t is typedefed to an 'unsigned int'
-
- >}
- >
- >The above class compiled and functioned successfully under version 3.0
- >but under version 3.1 I receive the error message:
- > "Reference initialized with 'double' requires lvalue of type 'double'"
- >which referred to the line I have indicated in the above class listing.
-
- Bad message; it should say something like "Reference initialized with
- 'huge double' requires lvalue of type 'near|far double'".
-
- >This contains no syntax error that I am aware of and is essentially given
- >in various textbooks on C++ as a method for implementing 'safe arrays'.
-
- Well, if you really need arrays over 64K, it's probably best that
- you're using a Vector class (a template would be even better) instead
- of polluting your code with 'huge'. Everything should work fine if
- you do something like:
-
- #if __TINY__ || __SMALL__ || __MEDIUM__
- #error My Vector class requires compact, large or huge memory model.
- #endif
- double& operator(unsigned long i) {
- return (double&)data[i-low];
- }
-
- Just be careful that you don't try to iterate through an array >64K
- with a regular pointer as only 'huge' pointers wrap correctly.
- Vector hugevec(MAX); ...
- for (double* d = &hugevec(0); d<=&hugevec(MAX-1); d++) // BAD!
-
- >Send any private responses to (I will make sure Jack gets them):
- >j_ohearn@dsg4.dse.beckman.com
-
- Okay. Btw, I just noticed there's an operator new() patch for BC++
- 3.1 at Simtel in borland/bc31p1.zip (something about assertion errors
- / aborts). See the comp.os.msdos.programmer FAQ if you don't know
- about Simtel. Also, Borland is supposed to release a DOS extender at
- the end of the year, so hopefully we won't have to mess with 64K
- limits for much longer.
-
- Jamshid Afshar
- jamshid@emx.utexas.edu
-
-
-