lomow@calgary.UUCP (04/04/87)
I have found a bug in release 1.2 of C++. Could you please look at the following description of the problem and either confirm or clear up the problem. I'm sorry if this problem has been previously reported, but it is new to me. The following program ////////// #include <stdio.h> #define NULL 0 class q_el { q_el *Next; public: q_el *next() { return Next;} q_el(q_el *n) { Next=n; } }; class d_q_el : public q_el { int Count; public: int count() { return Count;} d_q_el(q_el *n, int c) : (n) { Count = c; } }; main() { q_el *q; q = new d_q_el(NULL, 2); // will be at the end of the list q = new d_q_el(q, 1); // will be at the head of the list if ( ((d_q_el*)q) ->count() == 1) printf("ok\n"); if ( ((d_q_el*)q->next()) ->count() == 2) printf("ok\n"); if (q->d_q_el::count() == 1) printf("ok\n"); // *** the following line causes an internal error **** if (q->next()->d_q_el::count() == 2) printf("ok\n"); } ////////// causes the compiler to issue the following messages: % CC c.err.c CC c.err.c: "c.err.c", line 31: internal <<cfront 05/20/86>> error: bus error (or something nasty like that) 1 error % The problem seems to be the use of the scope resolution operator (i.e., '::') with a result returned from a function (or maybe it has to do with the way inline functions are expanded). The error can be eliminated by: 1) Commenting out line 30 (the line before the closing curly bracket of main()). or 2) Making Next a public data member of q_el and changing the calls to next() in main() to references to the variable Next - as shown in the following program. ////////// #include <stdio.h> #define NULL 0 class q_el { public: q_el *Next; // MOVED q_el *next() { return Next;} q_el(q_el *n) { Next=n; } }; class d_q_el : public q_el { int Count; public: int count() { return Count;} d_q_el(q_el *n, int c) : (n) { Count = c; } }; main() { q_el *q; q = new d_q_el(NULL, 2); q = new d_q_el(q, 1); if (((d_q_el*)q)->count() == 1) printf("ok\n"); if (((d_q_el*)q->Next)->count() == 2) printf("ok\n"); // CHANGED if (q->d_q_el::count() == 1) printf("ok\n"); if (q->Next->d_q_el::count() == 2) printf("ok\n"); // CHANGED } ////////// I prefer the following style if (q->next()->d_q_el::count() == 2) printf("ok\n"); to if ( ((d_q_el*)q->next()) ->count() == 2) printf("ok\n"); because the cast in the second if statement is hard to read. Would anyone care to comment? are there other alternatives? Thank You, Greg Lomow. Usenet: ....![ubc-vision,ihnp4]!alberta!calgary!lomow
bs@alice.UUCP (04/08/87)
lomow@calgary.UUCP (lomow @ U. of Calgary, Calgary, Ab.) writes: > I have found a bug in release 1.2 of C++. Could you please look > at the following description of the problem and either confirm > or clear up the problem. I'm sorry if this problem has been > previously reported, but it is new to me. > > The following program > > #include <stdio.h> > #define NULL 0 > > class q_el { > q_el *Next; > public: > q_el *next() { return Next;} > q_el(q_el *n) { Next=n; } > }; > > class d_q_el : public q_el { > int Count; > public: > int count() { return Count;} > d_q_el(q_el *n, int c) : (n) { Count = c; } > }; > > main() > { q_el *q; > q = new d_q_el(NULL, 2); // will be at the end of the list > q = new d_q_el(q, 1); // will be at the head of the list > > if ( ((d_q_el*)q) ->count() == 1) printf("ok\n"); > if ( ((d_q_el*)q->next()) ->count() == 2) printf("ok\n"); The following line contains an error: > if (q->d_q_el::count() == 1) printf("ok\n"); "q" is a pointer to a "q_el" and a "q_el" does not have a base class called "d_q_el". The member qualification syntax "class_name::member_name" is a mechanism for disambiguation and not a mechanism for breaking the type system. > // *** the following line causes an internal error **** > if (q->next()->d_q_el::count() == 2) printf("ok\n"); same bug, sorry about the poor error message. My latest cfront says: "", line 25: error: d_q_el is not a base class of q_el "", line 32: error: d_q_el is not a base class of q_el > } > causes the compiler to issue the following messages: > "c.err.c", line 31: internal <<cfront 05/20/86>> error: bus error (or something nasty like that) > I prefer the following style > if (q->next()->d_q_el::count() == 2) printf("ok\n"); > to > if ( ((d_q_el*)q->next()) ->count() == 2) printf("ok\n"); > because the cast in the second if statement is hard to read. > Would anyone care to comment? are there other alternatives? The cast notation is ugly because you are doing something ugly. Please don't misunderstand me: casts can be necessary, but I see no point in going out of my way to make them pleasing to the eye. There is a ``proper way'' of ``raising'' the type of a base class to that of the appropriate derived class: a virtual function call. Thank you for reporting the bug/problem. I have a point about style too: Don't use ``#define NULL 0''; it is redundant and classical C variations such as ``#define NULL ((char*)0)'' are potentially harmful.