home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / std / cplus / 1556 < prev    next >
Encoding:
Internet Message Format  |  1992-11-13  |  4.0 KB

  1. Path: sparky!uunet!know!mips2!news.bbn.com!usc!cs.utexas.edu!sdd.hp.com!hpscit.sc.hp.com!scd.hp.com!hpscdm!hpscdc!vinoski
  2. From: vinoski@ch.apollo.hp.com (Stephen Vinoski)
  3. Newsgroups: comp.std.c++
  4. Subject: Re: return values and destructors
  5. Message-ID: <BxMxxB.CMp@scd.hp.com>
  6. Date: 13 Nov 92 03:34:23 GMT
  7. References: <BxKs87.417@scd.hp.com> <1dsevkINNe8t@agate.berkeley.edu> <1992Nov12.132254.1@vax1.bham.ac.uk>
  8. Sender: news@scd.hp.com (News Account)
  9. Organization: Hewlett-Packard Corporation, Chelmsford, MA
  10. Lines: 74
  11.  
  12. In article <1992Nov12.132254.1@vax1.bham.ac.uk> mccauleyba@vax1.bham.ac.uk (Brian McCauley) writes:
  13. >I beg to differ I think that the behaviour of Cfront is a bug and that the
  14. >statement in the ARM is unambiguous if a little opaque. The redundant copy will
  15. >only be avoidable in cases where the return type is an inbuilt type and the
  16. >overhead of evaluating this before calling destructors and storing it away
  17. >somewhere is minimal. Also the return expression would have to not contain any
  18. >class types or even function calls as any class operation even on a object that
  19. >is not local may legitamately make use of local objects. (Consider a class that
  20. >has a static `population' member that is the total number of objects currently
  21. >existing. I agree the original example was contrived but I don't think it
  22. >should break a good complier. 
  23.  
  24. Actually the example is less contrived than you think.  Consider
  25. Stroustrup's "resource acquisition is initialization" idiom mentioned
  26. in his 2nd edition (sorry, I don't have it handy, otherwise I'd quote
  27. chapter and page).  This idiom calls for resources (heap storage,
  28. files, etc.) to be acquired via constructors and released via
  29. destructors, which is a useful approach especially when exceptions are
  30. involved.  Anyway, consider a mutex lock class that locks a mutex in
  31. its constructor and unlocks it in its destructor:
  32.  
  33. Foo
  34. func()
  35. {
  36.     static Foo foo;
  37.     Lock lock(foo.mutex);
  38.     // ...
  39.     return foo;
  40. }
  41.  
  42. In the presence of exceptions, this approach guarantees that locks are
  43. always released.
  44.  
  45. Clearly the programmer wants the value that foo has in the return
  46. statement to be returned to the caller.  Unfortunately, the current
  47. language definition does not guarantee that this will happen.  What
  48. could happen in this case is that the Lock object's destructor will
  49. execute when it goes out of scope, and the value of foo might change
  50. due to another thread of control before it is copied out to the
  51. caller.  In a multi-threaded environment, this is quite possible.
  52.  
  53. There is also a similar potential problem with exceptions and throw
  54. statements; what happens if the value of the thrown object is affected
  55. by the destructors executed due to stack unwinding before the throw
  56. actually occurs?
  57.  
  58. >In article <1dsevkINNe8t@agate.berkeley.edu>, jbuck@forney.berkeley.edu (Joe Buck) writes:
  59. >Again, I don't think so.  I'm not willing to pay the cost of the
  60. >extra copy operation that might be required were the committee to
  61. >force your example to work.  It's simply not worth slowing down reasonable
  62. >C++ programs to have defined behavior on your unreasonable example (it is
  63. >cute, though).  There is already precedent: the ANSI
  64. >C standard leaves the order of side effects explicitly undefined in
  65. >examples like
  66. >
  67. >    void func(int,int);
  68. >    int i = 3;
  69. >    func(i++,i++);
  70. >
  71.  
  72. I don't see how the fact that the order of side effects within a
  73. single statement is unspecified has anything at all to do with the
  74. problem I've brought up.  My problem involves side effects across
  75. multiple statements.  Aren't ANSI C "sequence points" designed to
  76. ensure that compilers behave identically in these situations?
  77.  
  78. The "resource acquisition is initialization" approach is already very
  79. common in C++.  In fact, the use of constructors and destructors in
  80. this manner is typically touted as being a strong feature of the
  81. language.  Unless the behavior of return statements vs. the
  82. side-effects of destructors is specified by the language, I'm afraid
  83. that this idiom becomes useless for a large class of programs.
  84.  
  85. -steve
  86.