* More questions... @ 1999-03-07 0:00 Michael Young 1999-03-08 0:00 ` Steve Doiel ` (3 more replies) 0 siblings, 4 replies; 9+ messages in thread From: Michael Young @ 1999-03-07 0:00 UTC (permalink / raw) I have two questions about Ada; more will certainly follow. 1) I've heard it said here that Ada, compared to other languages, is "reader-friendly" at the expense of being "writer-unfriendly". I understand the need to be reader friendly. I'm curious why you feel it is friendlier to read than, say, C++. 2) Robert Dewar stated some time ago that finalize should be used sparingly because of performance concerns. Is this still true of GNAT 3.11? More broadly, is this a language issue, or a feature specific only to certain GNAT or other implementation? Destructors in C++ are simply normal function calls. Are controlled types significantly different from other types to make this unrealistic? Thanks. Michael. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: More questions... 1999-03-07 0:00 More questions Michael Young @ 1999-03-08 0:00 ` Steve Doiel 1999-03-08 0:00 ` James S. Rogers ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: Steve Doiel @ 1999-03-08 0:00 UTC (permalink / raw) Michael Young wrote in message <7bvb4j$lt0$1@remarQ.com>... >I have two questions about Ada; more will certainly follow. > >1) I've heard it said here that Ada, compared to other languages, is >"reader-friendly" at the expense of being "writer-unfriendly". I >understand the need to be reader friendly. I'm curious why you feel it >is friendlier to read than, say, C++. > For an illustration, point your web browser to: http://www.lucent.com/ideas2/perspectives/bltj/ Select "Current" Then select "A Software Fault Prevention Approach in Coding and Root Cause Analysis". This document is not a contrast of Ada and C, it is an analysis of defects found in a sizable switching system that was implemented in C. The document gives a number specific examples of common coding errors found in the system. In my opinion none of these coding errors would be present if the code were written in Ada. These errors were the result of the tricky syntax in C. It may be easier to read "good" C code than "bad" Ada code. But with my luck (and experience) I am more likely to have to read "bad" C code and "average" Ada code. >2) Robert Dewar stated some time ago that finalize should be used >sparingly because of performance concerns. Is this still true of GNAT >3.11? More broadly, is this a language issue, or a feature specific only >to certain GNAT or other implementation? Destructors in C++ are simply >normal function calls. Are controlled types significantly different from >other types to make this unrealistic? > The use of finalization may add function calls to code that appears to consist of simple assignments. The same is true of C++. While I don't know how Ada and C++ compare when it comes to performance of Finalization versus destructors, both cases add a lot of hidden action to othewise simple looking code. SteveD ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: More questions... 1999-03-07 0:00 More questions Michael Young 1999-03-08 0:00 ` Steve Doiel @ 1999-03-08 0:00 ` James S. Rogers 1999-03-08 0:00 ` Hyman Rosen 1999-03-09 0:00 ` Samuel Mize 1999-03-09 0:00 ` Samuel Mize 3 siblings, 1 reply; 9+ messages in thread From: James S. Rogers @ 1999-03-08 0:00 UTC (permalink / raw) Michael Young wrote in message <7bvb4j$lt0$1@remarQ.com>... >I have two questions about Ada; more will certainly follow. > >1) I've heard it said here that Ada, compared to other languages, is >"reader-friendly" at the expense of being "writer-unfriendly". I >understand the need to be reader friendly. I'm curious why you feel it >is friendlier to read than, say, C++. C and, because of C compatibility, C++ syntax is written to minimize the number of keystrokes required to create a program. In the early 1970's this was viewed as a way of increasing programmer productivity. Unfortunately, C++ has taken the very terse syntax of C and added new functionality while trying not to increase the number of additional keywords and operators. The result is a heavy overloading of already heavily overloaded operators. Think of all the uses of the '*' and '&' operators in C++. Correct understanding of these operators is highly context dependent. Some examples taken from page 79 of "Object Oriented Programming Using C++" by Ira Pohl: int i = 5; // i is located in memory with rvalue 5 int* p = &i; // p is located in memory with rvalue &i int& r = i; // r and i are the same object int&* s = p; // s and p are the same object Now, the example above seems a little confusing. It claims that r and i are the same object. At the same time it is true that references such as r are implemented using pointers. C++ simply provides a cleaner and safer way to use a pointer when it is declared as a reference. The statement above would lead you to believe that r is merely an alias for i. The nearest Ada equivalents to the C++ examples above are: i : aliased integer := 5; -- i is located in memory and is initialized with the 5 type Int_Access is access all integer; -- define a general access type p : Int_Access := i'access; -- p is located in memory with value of i'access Ada does not have a direct equivalent to references. In fact, Ada access types are as safe as C++ references while also being useful in all Ada data structures. C++ references are always constants. A reference cannot change the object it references. The reference object may or may not be constant. C++ reference types cannot be elements of an array because references must be initialized, while arrays cannot be initialized in C++. As far as how readable the two languages are, try the following test. Find a person who does not know Ada or C++. Show that person the following code fragments. #include <streams.h> main () { for(int Count = 1; Count < 11; Count++) cout << Count << endl; } with Ada.Text_Io; procedure Count_To_Ten is begin for Count in 1..10 loop Ada.Text_Io.Put_Line(Integer'Image(Count)); end loop; end Count_To_Ten; Ask this person what each code fragment does. >2) Robert Dewar stated some time ago that finalize should be used >sparingly because of performance concerns. Is this still true of GNAT >3.11? More broadly, is this a language issue, or a feature specific only >to certain GNAT or other implementation? Destructors in C++ are simply >normal function calls. Are controlled types significantly different from >other types to make this unrealistic? This is not a compiler specific issue. It is a language level issue. Controlled types have the overhead of calling finalize each time an object of the controlled type goes out of scope. Other types in Ada do not call a finalize procedure when they go out of scope. Finalization is also called during assignment operations for all temporary objects created and destroyed during the actual assignment operation. Ada uses temporary objects so that the case where A := A is properly handled. C++ needs constructors for all classes because C++ requires dynamic allocation and deallocation of objects to achieve polymorphism. Ada allows the programmer to decide whether or not to use dynamic allocation and deallocation. Ada can achieve polymorphism with or without dynamic allocation. This means that Ada does not always need a destructor. Robert Dewar was warning against the use of Controlled types because they impose an overhead which may not be necessary. If your design uses no dynamic allocation you may not need the facilities of Controlled types. Jim Rogers Colorado Springs, Colorado ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: More questions... 1999-03-08 0:00 ` James S. Rogers @ 1999-03-08 0:00 ` Hyman Rosen 1999-03-10 0:00 ` Matthew Heaney 0 siblings, 1 reply; 9+ messages in thread From: Hyman Rosen @ 1999-03-08 0:00 UTC (permalink / raw) "James S. Rogers" <jimmaureenrogers@worldnet.att.net> writes: > int& r = i; // r and i are the same object > Now, the example above seems a little confusing. > It claims that r and i are the same object. It is not confusing at all. In fact, r and i *are* the same object. > At the same time it is true that references such as r are > implemented using pointers. The fact that *in some cases* a pointer to the referenced object may be created by the implementation is completely irrelevant to the C++ concept that a reference is an alias of the referenced object. > C++ simply provides a cleaner and safer way to use a pointer when it > is declared as a reference. The statement above would lead you to > believe that r is merely an alias for i. In C++, references are not pointers. They are aliases for objects. A reference always refers to the same object from the moment it is created. It is true that careless programming can leave a reference dangling by destroying its aliased object out from under it, since, as has been mentioned here before, C++ defaults to "unsafe". > Ada does not have a direct equivalent to references. In fact, Ada > access types are as safe as C++ references while also being useful > in all Ada data structures. C++ reference types have little to do with safety, and much to do with operator overloading. Their main purpose is to permit the return value of a function to be the alias of an existing object, so that further operations may be performed on it, and to avoid copying of possibly large objects as function parameters. template <typename T, int N> class fixed_array { T theArray[N]; public: T &operator[] (int n) { return theArray[n]; } }; fixed_array<double, 6> b; b[3] = 7.9; > C++ references are always constants. A reference cannot change the object > it references. The reference object may or may not be constant. > C++ reference types cannot be elements of an array because references must > be initialized, while arrays cannot be initialized in C++. A much better analogy is to compare C++ references with Ada procedure parameters. The compiler must (I believe) implement pass-by-reference for at least certain kinds of parameters. In Ada, you certainly would not expect to be able to reseat a procedure parameter to refer to some object other than the one passed, nor would you expect to be able to have an array of in out parameters! > As far as how readable the two languages are, try the following > test. Find a person who does not know Ada or C++. Show that person > the following code fragments. This is a straw man. Certainly no programming language is designed to be understood by people who do not know it! > cout << Count << endl; > Ada.Text_Io.Put_Line(Integer'Image(Count)); > > Ask this person what each code fragment does. I suspect that the person would wonder where the forgotten close quote goes in the Ada code. If he wanted to print two numbers on the same line, he might wonder what to call, assuming he even realized that put_line appended the terminator. Once he knew C++, he might wonder why he had to name the type of Count when trying to print it. > C++ needs constructors for all classes because C++ requires dynamic > allocation and deallocation of objects to achieve polymorphism. Ada > allows the programmer to decide whether or not to use dynamic > allocation and deallocation. Ada can achieve polymorphism with or > without dynamic allocation. This means that Ada does not always need > a destructor. Once again, this is vastly confused. First, C++ does *not* need constructors for all classes. Constructors and destructors are used to appropriately initialize and clean up objects. When no such work is needed the construct does not need to appear. And one can have either a constructor or destructor without the other. Second, it is false as well that dynamic allocation is required for polymorphism. Objects may be created dynamically on the heap, automatically on the stack, or statically in fixed memory, and they will all act polymorphically if they are part of a polymorphic hierarchy. > Robert Dewar was warning against the use of Controlled types because they > impose an overhead which may not be necessary. If your design uses no > dynamic allocation you may not need the facilities of Controlled types. I don't remember that thread, but I assume that he is correct. I also assume that he may at this moment be writing to correct your mistakes just as I am! ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: More questions... 1999-03-08 0:00 ` Hyman Rosen @ 1999-03-10 0:00 ` Matthew Heaney 0 siblings, 0 replies; 9+ messages in thread From: Matthew Heaney @ 1999-03-10 0:00 UTC (permalink / raw) Hyman Rosen <hymie@prolifics.com> writes: > "James S. Rogers" <jimmaureenrogers@worldnet.att.net> writes: > > Ada does not have a direct equivalent to references. In fact, Ada > > access types are as safe as C++ references while also being useful > > in all Ada data structures. > > C++ reference types have little to do with safety, and much to do with > operator overloading. Their main purpose is to permit the return value > of a function to be the alias of an existing object, so that further > operations may be performed on it, and to avoid copying of possibly > large objects as function parameters. The mechanism for this sort of thing in Ada is to have a function that returns a pointer designating the object, and then dereference the result of the function. For example, suppose you have a stack of integers. The bullet-proof way to set the top item via a "reference" (really, a pointer) is to declare the operation function Set_Top (Stack : access Stack_Type) return Item_Access; and then do this: Set_Top (Stack'Access).all := 10; Using this approach, you can never have a dangling reference. It's not as nice as the C++ way: Set_Top (Stack) := 10; but it's reasonably close. In Ada95 you pay a small amount of syntactic overhead, but the benefit is that you can't get a dangling reference. If you know what you're doing, you can shorten the statement to Set_Top (Stack).all := 10; I discuss this technique in my article "Collections of Limited Items" in the ACM patterns archive. <http://www.acm.org/archives/patterns.html> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: More questions... 1999-03-07 0:00 More questions Michael Young 1999-03-08 0:00 ` Steve Doiel 1999-03-08 0:00 ` James S. Rogers @ 1999-03-09 0:00 ` Samuel Mize 1999-03-09 0:00 ` Samuel Mize 3 siblings, 0 replies; 9+ messages in thread From: Samuel Mize @ 1999-03-09 0:00 UTC (permalink / raw) Michael Young <nobody@all.org> wrote: > 1) I've heard it said here that Ada, compared to other languages, is > "reader-friendly" at the expense of being "writer-unfriendly". I > understand the need to be reader friendly. I'm curious why you feel it > is friendlier to read than, say, C++. This is more a touchstone for comparing possible language constructs to put into Ada, than a touchstone for comparing Ada to other languages. And I'm not sure that "friendly" is the most accurate term for it. That's a subjective judgement, and some people find while (*a++=*b++); to be "friendlier" than the Ada equivalent. I'd say that the idea is that the reader's first impression of the code should be both unambiguous and correct. One element is explicitness over conciseness. For instance, in Ada, you can freely convert between separate integer types, just as you can in C (and I assume in C++). However, you have to explicitly state that you are doing so. Aside from detecting typos (and thinkos), this tells the later code reader that you really did intend to do that. Best, Sam Mize -- Samuel Mize -- smize@imagin.net (home email) -- Team Ada Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: More questions... 1999-03-07 0:00 More questions Michael Young ` (2 preceding siblings ...) 1999-03-09 0:00 ` Samuel Mize @ 1999-03-09 0:00 ` Samuel Mize 1999-03-09 0:00 ` Hyman Rosen 1999-03-10 0:00 ` robert_dewar 3 siblings, 2 replies; 9+ messages in thread From: Samuel Mize @ 1999-03-09 0:00 UTC (permalink / raw) Michael Young <nobody@all.org> wrote: > 2) Robert Dewar stated some time ago that finalize should be used > sparingly because of performance concerns. ... > Destructors in C++ are simply > normal function calls. Are controlled types significantly different from > other types to make this unrealistic? Was he saying that Finalize should be used sparingly compared to C++ destructors? I would assume that he was saying it should not be used unless needed, because it adds a function call at every assignment statement, and when the variable goes out of scope. Ada is often used in time-critical embedded systems, where needless procedure-call overhead may be a significant cost. OTOH, when you assign a new value to an object with a destructor, does C++ call the destructor before assigning the new value? Or is that even a meaningful question for C++? Best, Sam Mize -- Samuel Mize -- smize@imagin.net (home email) -- Team Ada Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: More questions... 1999-03-09 0:00 ` Samuel Mize @ 1999-03-09 0:00 ` Hyman Rosen 1999-03-10 0:00 ` robert_dewar 1 sibling, 0 replies; 9+ messages in thread From: Hyman Rosen @ 1999-03-09 0:00 UTC (permalink / raw) Samuel Mize wrote: > OTOH, when you assign a new value to an object with a destructor, does > C++ call the destructor before assigning the new value? Or is that even > a meaningful question for C++? In C++ classes may have user-defined assignment operators. If a class has such a thing, then it is invoked when the assignment is done, and it is responsible for doing the necessary cleanup work. If a class does not have a user-defined assignment operator, then the default behavior is to treat assignment as a field-by-field copy, recursively invoking other user-defined assignment operators if fields are themselves class objects. Note that in C++, assigning to an object does not have the semantics of destroying the object and replacing it with a new one. The object is considered to be the same before and after the assignment. It merely has had its value changed in some fashion. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: More questions... 1999-03-09 0:00 ` Samuel Mize 1999-03-09 0:00 ` Hyman Rosen @ 1999-03-10 0:00 ` robert_dewar 1 sibling, 0 replies; 9+ messages in thread From: robert_dewar @ 1999-03-10 0:00 UTC (permalink / raw) In article <7c40uu$14lu@news3.newsguy.com>, Samuel Mize <smize@imagin.net> wrote: > Was he saying that Finalize should be used sparingly > compared to C++ destructors? No, he was not :-) > > I would assume that he was saying it should not be used > unless needed, because it adds a function call at every > assignment statement, and when the variable goes out of > scope. That's what he was saying! -----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~1999-03-10 0:00 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1999-03-07 0:00 More questions Michael Young 1999-03-08 0:00 ` Steve Doiel 1999-03-08 0:00 ` James S. Rogers 1999-03-08 0:00 ` Hyman Rosen 1999-03-10 0:00 ` Matthew Heaney 1999-03-09 0:00 ` Samuel Mize 1999-03-09 0:00 ` Samuel Mize 1999-03-09 0:00 ` Hyman Rosen 1999-03-10 0:00 ` robert_dewar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox