Topic: g++ problem
Author: tompkinsjd@watt.ccs.tuns.ca
Date: 6 Feb 92 15:56:54 -300 Raw View
I am having a problem with the GNU C++ tools. I have a
piece of code which will not compile under GNU, but will
compile under Borland C++, and Turbo C++.
The version of the GNU tools being used are:
gcc 1.40.0
g++ 1.40.3
libg++ 1.39.0
These are the latest available from prep.ai.mit.edu.
This is the type of message which g++ gives:
Node.cc: In method class Terminal &Node::GetInTerm (int):
Node.cc:36: type `Terminal' is not a base type for type `Element'
Could someone explain what is happening here? Is this caused
by differences in the C++ versions which the compilers support, or
is there something wrong with my g++ installation?
Any replies greatly appreciated.
Jim Tompkins
Electrical Engineering Dept.
Technical University of Nova Scotia
Halifax, NS, CANADA
email : jdt@tuns.ca
>>>>>>>>>>>>>>>>>> cut here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// Element is the base class
class Element {
Element *next;
public:
// This function returns a pointer to an Element
Element *GetInByIndexp(int i) { return next; }
};
// Node and Terminal are derived classes from the Element class
class Terminal : Element {
};
class Node : Element {
// Member functions
public:
Terminal* GetInTermp(int i);
Terminal& GetInTerm(int i);
};
// This function works OK. It does a cast from an Element pointer
// to a Terminal pointer.
Terminal* Node::GetInTermp(int i)
{
return (Terminal*) GetInByIndexp(i);
}
// This function does not work.
Terminal& Node::GetInTerm(int i)
{
return (Terminal&) *(GetInByIndexp(i));
}
Author: jamshid@ut-emx.uucp (Jamshid Afshar)
Date: 13 Feb 92 11:45:47 GMT Raw View
In article <1992Feb6.155654.1@watt.ccs.tuns.ca> tompkinsjd@watt.ccs.tuns.ca
writes:
> I am having a problem with the GNU C++ [1.40.3] tools. I have a
>piece of code which will not compile under GNU, but will
>compile under Borland C++, and Turbo C++.
The code does something like:
class Element { };
class Terminal : public Element { };
Element* foo();
Terminal* terminalp() {
return (Terminal*) foo(); // g++ accepts
}
Terminal& terminalr();
return (Terminal&) *(foo()); // g++ gives error
}
Apparently the current version of g++ (gcc 2.0 will be more ARM
conforming) isn't following the ARM 5.4 rule that "An object may be
explicitly converted to a reference type X& if a pointer to that
object may be explicitly converted to an X*." Of course, the run-time
results are undefined if you are wrong about the cast (ie, the object
really isn't an X), but the compiler must compile the code and it must
work if the object is really the casted type.
I've heard some people say that casting to reference should only be
accepted by the compiler if it is a "safe" cast (eg, casting to a base
class when using multiple-inheritance). That seems to be what g++ is
doing (though I don't know if any other C++ compiler ever has).
The reasoning is that programmers can use pointer casting when they
want to tell the compiler "I know what I'm doing!", and reference
casting when they want to tell the compiler "treat my DrawableDeck
object as a Shape here because I want to call draw(Shape&) instead of
draw(Deck&), but don't let me do something stupid like
draw((Shape&)dd_ptr)". That would have been nice, but getting your
compiler to add an optional warning is about all that can be done now.
Jamshid Afshar
jamshid@emx.utexas.edu