From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fac41,9a0ff0bffdf63657 X-Google-Attributes: gidfac41,public X-Google-Thread: f43e6,9a0ff0bffdf63657 X-Google-Attributes: gidf43e6,public X-Google-Thread: 1108a1,9a0ff0bffdf63657 X-Google-Attributes: gid1108a1,public X-Google-Thread: 103376,4b06f8f15f01a568 X-Google-Attributes: gid103376,public From: dewar@merv.cs.nyu.edu (Robert Dewar) Subject: Re: Why C++ is successful Date: 1998/08/08 Message-ID: X-Deja-AN: 379137675 References: <6qfhri$gs7$1@nnrp1.dejanews.com> <35cb8058.645630787@news.ne.mediaone.net> X-Complaints-To: usenet@news.nyu.edu X-Trace: news.nyu.edu 902579239 14132 (None) 128.122.140.58 Organization: New York University Newsgroups: comp.lang.eiffel,comp.object,comp.software-eng,comp.lang.ada Date: 1998-08-08T00:00:00+00:00 List-Id: Timothy Welch says <<>(1) Doesn't distinguish between pointers to local variables and pointers > to heap allocated memory. > >(2) Allows you to get a pointer to any local variable, rather than forcing > you to be explicit about which local variables can be pointed to, or > "aliased". > >(3) Makes it easy to do all kinds of other arbitrary weird things with > pointers. > Out of curiousity why are (1) and (2) problems? Can't the GC just check to see if the pointer is pointing to memory on the stack? >> Undoubtedly at least *part* of the problem in using C is that people are not sufficiently aware of what can go wrong. Microsoft has a rather amazing book that pretends to be a book about software techniques, but in fact is little more than a set of perfectly standard coding procedures to avoid pitfalls in C. When I read it, I was surprised that professional C programmers would find such a book useful, but the questions above are a reminder that you often people are not aware of the dangers. I must say I worry about CS curriculums in which people are only getting exposed to C and C++ and hence simply don't register important language design principles (after all the idea that it is obviously a bad idea to allow pointers to local variables is a very old one, dating back at least to Pascal, which means coming up to 30 years. Timothy, to answer your questions. (1) is a serious problem, since it can allow dangling pointers. That is, when you leave a scope with such a pointer, then you have a pointer to inactive stack. Using this pointer later on can cause serious damage, e.g. clobbering a return point stored on the stack. These dangling pointers are created even though you never use free. There is no practical implementation mechanism for efficiently detecting such a dangling pointer. (2) is of course related, but is at a more conceptual level. Aliasing is always dangerous because it can cause code to be very difficult to read, understand, and maintain (as well as leading to accidental bugs in the first place). Consider in C: (everything is an int or a *int) a = b; c = 3 + q; *d = 4; That assignment to *d *may* modify the values of a and c. This means you cannot just read ahead in the code at this stage, you have to ensure that it is not possible for d to be pointing to a or c, or worse discover that it is possible, and that one of the first two assignments is dead. A (good) compiler will make an attempt to determine the answer (it is not always possible to do this reliably). A compiler that does not make this effort risks generating horrible code for the above, since it has to forget the values of a and c in registers. A compiler that tries hard still often finds that it has to be conservative and assume the worst. A (good) programmer will make an attempt to determine the answer (it is not always possible to do this reliably). A programmer that does not make this effort risks seriously misunderstanding the above, since they will have to forget the assigned values of a and c. A programmer that tries hard still often finds that they have to be conservative and assume the worst. Note the parallel language here is quite deliberate. Whey you set obstacles for a compiler, you set them for a programmer as well. A clever compiler can compensate, and that's OK, since machine time is cheap, so what if the compilation takes longer (but as noted, even a clever compiler can be fooled). A clever programmer can compensate, and that is NOT OK, since programmer time is not cheap, and maintenance mistakes are very costly. In Pascal and Ada 83, a decision was made to completely disallow pointers to local variables, and this is undoubtedly the best decision from a language point of view. However, especially when interfacing to other languages, this proves an annoying restriction. For example, if you are interfacing to a language like C that typically requires pointers to parameters to be passed, then it is annoying not to be able to pass pointers to local variables. Ada 83 programmers would often resort to nasty low level junk (i.e. use of the 'Address attribute) for this purpose, leading to code that has all the disadvantages discussed above, and more. Why more? Becuase (a) address gives untyped pointers, like void*, and (b) the semantics of whether the aliasing attempt "works" correctly is not clear from the standard. Ada 95 compromises by allowing you to declare a variable as aliased, which means that it is allowable to take its "address", using the strongly typed 'Access attribute. An Ada 95 program that declared every local variable to be aliased would be equivalent to the C semantics (it would also be a travesty!) Generally you should alias local variables ONLY in connection with interfacing to foreign code. Yes, as with all rules, including this one, there are exceptions to this rule that are legitimate, but if you find you are using aliased extensively, something may be wrong with your approach. Robert Dewar P.S. with respect to the GC part of your question, sure, you can determine that a pointer points to the stack, but the dangling pointer case can cause unimaginable chaos in a garbage collector. Indeed the combination of garbage collection with semantics that allow dangling pointers is a dangerous one, dangerous enough to make a language design quite dubious from a practical point of view.