[fpc-devel] Circular references and forward declarations
Juha Manninen
juha.manninen at phnet.fi
Tue Jan 5 17:07:43 CET 2010
Hello.
My proposal:
Please allow a forward declaration of a class which is defined in another
unit, maybe using a new syntax for the declaration.
Alternatively, allow circular references just like other programming languages
do.
Forbidden circular references is a major annoyance in Object Pascal and one of
the main (!) reasons why it is not popular for big projects.
I remember comments from other programmers like: "Delphi is not suitable for
serious SW projects because the source files can't reference each other and
you must put everything into one big file."
Then I was arguing that no, it is not true, there are ways to go around it.
Later I did some "serious SW projects" with Delphi and changed my mind.
The problem is about referencing classes between units. Say you have unit
MyUnit defining class TMyClass. In a typical circular reference situation you
must define a variable MyVar as TObject (although it's actually TMyClass) and
then cast it in the implementation section as TMyClass(MyVar).
Very clumsy! And worse, you can't use the nice code completion features of
your IDE when the variable is defined as "TObject".
One suggestion has been to create an abstract base class into a separate unit
and reference that in both the inherited class's unit and in the dependent
unit. Well, I tried that.
First, it creates a completely useless unit, making the code harder to
understand.
Second, it didn't solve the problem. In REAL programming situations I
sometimes had to refer to data members in the inherited class (not included in
the abstract base class to avoid circular reference). Then I again had to cast
the variable which effectively nullified the whole effort. I could have used
the "TObject method" as well.
Finally I gave up and copy-pasted everything into one big unit. That's
apparently what all "serious" Object Pascal projects must do. Virtual TreeView
is one big file. Lazarus has units of almost 20 000 lines. It is really too
much. Or, it would be ok if the programmer really wanted to do so but the
compiler should not force it!
Think of this:
Forward declaration of a class is allowed inside a unit. There can be a
reference to a class before it is defined! Like:
TMyClass = class;
Why is it not allowed from another unit? They are conceptually the same thing!
The problem could be solved easily if there was a forward declaration saying:
TMyClass = class; defined in "MyUnit.pas"
or
TMyClass = class; defined outside
or whatever...
That would not create a circular reference error because MyUnit would not be
in uses clause. IMO, simply allowing circular reference would be the easiest
solution but maybe it creates some technical problem which I don't know
about... Well, most other languages can do it...
Many people asked about circular reference in Delphi mailing lists. The
answers were basically like: "This is the way it is defined and it will not
change."
Most programmers have switched to some other programming language.
What a surprise!
If I create a feature request issue for this, does it have any chance of being
implemented? I think it would be EASY to implement. Some other features like
generics and closures (anonymous functions) need much more effort.
Yours,
Juha Manninen
More information about the fpc-devel
mailing list