home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / lang / cplus / 11613 < prev    next >
Encoding:
Internet Message Format  |  1992-07-27  |  4.3 KB

  1. Path: sparky!uunet!cs.utexas.edu!ut-emx!jamshid
  2. From: jamshid@ut-emx.uucp (Jamshid Afshar)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Borland C++ 3.1 fails to conform to C++ Standard
  5. Summary: 'huge' is not Standard C++
  6. Keywords: C++ Standard
  7. Message-ID: <76636@ut-emx.uucp>
  8. Date: 27 Jul 92 07:54:29 GMT
  9. References: <j_ohearn.711991770@dn73>
  10. Reply-To: jamshid@emx.utexas.edu
  11. Followup-To: comp.os.msdos.programmer
  12. Organization: The University of Texas at Austin; Austin, Texas
  13. Lines: 96
  14.  
  15. As the crux of the problem is related to a common MS-DOS C/C++
  16. compiler extension, I have redirected followups to
  17. comp.os.msdos.programmer.
  18.  
  19. In article <j_ohearn.711991770@dn73> j_ohearn@dsg4.dse.beckman.com writes:
  20. >class Vector
  21. >{
  22. >    double huge *data;
  23.  
  24. First, there is no Standard C++ yet.  Second, I'm sure it will not
  25. contain the modifier 'huge', so it's not quite valid to claim Borland
  26. is nonconforming because of a problem related to the use of that keyword.
  27.  
  28. >    public: [...]
  29. >    double& operator()( unsigned long i ) {
  30. >        return data[i - low]; //Line that offends ver 3.1 but compiled without
  31. >    }                         //error under 3.0
  32. >};
  33.  
  34. You declare operator() as returning a reference to a double.
  35. Depending on which memory model you are compiling under, pointers and
  36. references are assumed to be either 'near' or 'far' (never 'huge'; not
  37. even in the huge memory model).  'data' is a 'huge' pointer so you are
  38. actually returning a 'double huge&' from within operator().
  39. Therefore, you're assigning a 'double huge&' to either a 'double
  40. near&' (unsafe conversion) or a 'double far&' (safe, but still a
  41. conversion).  According to the ARM 8.4.3, a non-const reference can
  42. only be initialized by an object of the exact same type -- no
  43. conversions are allowed.  Earlier C++ rules (which BC++ 3.0 implemented
  44. with a warning) said that a temporary would be created and the
  45. reference would be initialized to that.  Now only const references can
  46. create a temporary.
  47.     const double& d2 = 1;  // okay, temporary "1.0" generated
  48.     double& d1 = 1;  // error, but earlier rules would generate temporary
  49.  
  50. Of course, how the above ARM rule applies to an MS-DOS extensions like
  51. 'huge'/'far'/'near' is up to the compiler maker (another good reason
  52. not to use extensions), but BC++ 3.1's behavior does seem to be
  53. consistent with the "standard" part of the language.
  54.  
  55. >Vector::Vector(unsigned long L, unsigned long H)
  56. >{
  57. >    low = L;
  58. >    high = H;
  59. >    data = new double huge[H - L + 1];
  60.  
  61. So that's how you get 'new' to allocate over 64K objects!  This is
  62. analogous to farmalloc().  It calls Borland's
  63.     void* operator new(unsigned long);
  64. instead of
  65.     void operator new(size_t);  // size_t is typedefed to an 'unsigned int'
  66.  
  67. >}
  68. >
  69. >The above class compiled and functioned successfully under version 3.0 
  70. >but under version 3.1 I receive the error message:
  71. >    "Reference initialized with 'double' requires lvalue of type 'double'"
  72. >which referred to the line I have indicated in the above class listing.
  73.  
  74. Bad message; it should say something like "Reference initialized with
  75. 'huge double' requires lvalue of type 'near|far double'".
  76.  
  77. >This contains no syntax error that I am aware of and is essentially given 
  78. >in various textbooks on C++ as a method for implementing 'safe arrays'.
  79.  
  80. Well, if you really need arrays over 64K, it's probably best that
  81. you're using a Vector class (a template would be even better) instead
  82. of polluting your code with 'huge'.  Everything should work fine if
  83. you do something like:
  84.  
  85. #if __TINY__ || __SMALL__ || __MEDIUM__
  86. #error My Vector class requires compact, large or huge memory model.
  87. #endif
  88.     double& operator(unsigned long i) {
  89.        return (double&)data[i-low];
  90.     }
  91.  
  92. Just be careful that you don't try to iterate through an array >64K
  93. with a regular pointer as only 'huge' pointers wrap correctly.
  94.     Vector hugevec(MAX); ...
  95.     for (double* d = &hugevec(0); d<=&hugevec(MAX-1); d++)  // BAD!
  96.     
  97. >Send any private responses to (I will make sure Jack gets them):
  98. >j_ohearn@dsg4.dse.beckman.com
  99.  
  100. Okay.  Btw, I just noticed there's an operator new() patch for BC++
  101. 3.1 at Simtel in borland/bc31p1.zip (something about assertion errors
  102. / aborts).  See the comp.os.msdos.programmer FAQ if you don't know
  103. about Simtel.  Also, Borland is supposed to release a DOS extender at
  104. the end of the year, so hopefully we won't have to mess with 64K
  105. limits for much longer.
  106.  
  107. Jamshid Afshar
  108. jamshid@emx.utexas.edu
  109.  
  110.  
  111.