Google Grupper har inte längre stöd för nya Usenet-inlägg eller -prenumerationer. Historiskt innehåll förblir synligt.
Dismiss

Forward reference not allowed.. ?

57 visningar
Hoppa till det första olästa meddelandet

Red Orchid

oläst,
3 aug. 2003 11:38:432003-08-03
till
the codes as follows:
// # 1
type
TTest1 = class
private
SStr: String;
end;
TTest2 = class
private
IInt: Integer;
CCls: TTest1; // : OK
end;
//

// # 2
type
TTest2 = class
private
IInt: Integer;
CCls: TTest1; // : compile error (Undeclared identifier)
end;
TTest1 = class
private
SStr: String;
end;
//

as far as i know,
lonnnnnng ago, there was 1-pass compiler.
this compiler did not allow forward reference.
lonnng ago, there was 2-pass compiler.
this compiler allowed forward reference.

from 'lonnnnnng ago' to 'the present', there was/is the object pascal.

what reason that the object pascal did/do not allow forward reference?

so far as i know, a compiler did not allow forward reference in the past.

your opinion?

Regards
--
Red Orchid

Ignacio Vazquez

oläst,
3 aug. 2003 11:39:412003-08-03
till
"Red Orchid" <redo...@invalid.invalid> wrote in message
news:3f2d...@newsgroups.borland.com...

> what reason that the object pascal did/do not allow forward reference?

It does allow it, provided it's in the same type block. Look up "Forward
Declarations" in the Delphi help.

Cheers,
Ignacio


Ignacio Vazquez

oläst,
3 aug. 2003 12:22:112003-08-03
till
"Red Orchid" <redo...@invalid.invalid> wrote in message
news:3f2d...@newsgroups.borland.com...
> > It does allow it, provided it's in the same type block. Look up
> "Forward
> > Declarations" in the Delphi help.
>
> i think it is not forward *reference*.
> a programmer should write 'forward declaration' in delphi.
> in the codes mentioned above, it is 'TFigure = class;'.
> is it desirable that a compiler do it?

>
> so far as i know,
> the modern language conception don't require 'forward declaration'.

Silly me, I read your question wrong.

Delphi doesn't allow forward references so that it can compile in one pass.
The reason for this is speed, plain and simple. It could allow it by doing
two passes, but then it wouldn't be the fastest compiler on the market ;)

Cheers,
Ignacio


Red Orchid

oläst,
3 aug. 2003 12:20:002003-08-03
till
> It does allow it, provided it's in the same type block. Look up
"Forward
> Declarations" in the Delphi help.
>

delphi's help says as followings:
//
type
TFigure = class; // forward declaration
TDrawing = class
Figure: TFigure;
...
end;
TFigure = class // defining declaration
Drawing: TDrawing;
...
end;
//

i think it is not forward *reference*.
a programmer should write 'forward declaration' in delphi.
in the codes mentioned above, it is 'TFigure = class;'.
is it desirable that a compiler do it?

so far as i know,

the modern language conception don't require 'forward declaration'.

--
Red Orchid

Danny Thorpe

oläst,
3 aug. 2003 20:06:382003-08-03
till

"Red Orchid" <redo...@invalid.invalid> wrote in message
news:3f2d...@newsgroups.borland.com...
> as far as i know,
> lonnnnnng ago, there was 1-pass compiler.
> this compiler did not allow forward reference.
> lonnng ago, there was 2-pass compiler.
> this compiler allowed forward reference.
>

Actually, multipass was the earlier compiler architecture. Each phase of
the compile process was done by a different program. Life was simple, but
compiling took forever because the symbol information kept going back and
forth between disk and memory.

Single pass compilers didn't appear until much later, and even then only for
languages whose structure allows top-down compilation.

-Danny

Chris Burrows

oläst,
3 aug. 2003 20:38:102003-08-03
till
"Danny Thorpe" <nom...@borland.com> wrote in message
news:3f2da328$1...@newsgroups.borland.com...

>
> Actually, multipass was the earlier compiler architecture. Each phase of
> the compile process was done by a different program. Life was simple, but
> compiling took forever because the symbol information kept going back and
> forth between disk and memory.
>
> Single pass compilers didn't appear until much later, and even then only
for
> languages whose structure allows top-down compilation.
>

There is a little more to it than that as you maybe aware. Multi Pass
compilers are often implemented today, even where the language definition
does not require it:

a) To allow advanced optimisation techniques which require data flow
analysis

b) To enhance portability. This can be done by separating the front-end and
the back-end into language-dependent and machine-dependent parts.

Refer to "Compiler Construction - The Art of Niklaus Wirth" by Hanspeter
Mossenbock for more detail.

http://www.informatik.uni-trier.de/~ley/db/conf/birthday/wirth2000.html

Chris Burrows
CFB Software
http://www.cfbsoftware.com


Danny Thorpe

oläst,
3 aug. 2003 23:48:332003-08-03
till

"Chris Burrows" <in...@cfbsoftware.com> wrote in message
news:3f2daae9$1...@newsgroups.borland.com...

>
> There is a little more to it than that as you maybe aware. Multi Pass
> compilers are often implemented today, even where the language definition
> does not require it:
>
> a) To allow advanced optimisation techniques which require data flow
> analysis
>
> b) To enhance portability. This can be done by separating the front-end
and
> the back-end into language-dependent and machine-dependent parts.
>

If you want to get technical, the Delphi compiler is a multipass
architecture as well. The compiler builds an intermediate representation
node tree while parsing a procedure body. When it reaches the end of the
procedure body, it makes multiple optimization passes over the node tree,
then emits machine code into unit storage. The node tree is destroyed and
the parser scans for the next procedure body. Smart linking the symbols
into a final executable is also a multi-pass process.

The part that matters to the original question is the parser, the thing that
gives symbolic meaning to identifiers in context. That is single-pass in
Delphi and in most C and C++ compilers. Symbol recognition in C# and Java
cannot begin until the entire source file and all dependencies have been
scanned completely.

-Danny

Peter Thönell

oläst,
4 aug. 2003 02:52:472003-08-04
till

> what reason that the object pascal did/do not allow forward reference?
...
> your opinion?

My opinion is that in a single pass compiler, the compiler must know what
something is before it can accept it.

ex.
TMyRec = record
int: integer; // it knows what this is
SubRec: TSubRec; // but what is this?
end;

SubRec could be of any size. But old Pascal did allow this:

PListNode = ^TListNode;
TListNode = record
Data: ....;
Next: PListNode;
end;

Because PListNode was declared as a pointer, when the compiler reached Next
it knew that PListNode was a pointer, of some unkown sort. A pointer is a
pointer, so it could deal with this.

Same thing with:
TMyClass = class;

TOther = class
fMyClass: TMyClass;
end;

TMyClass = class
...
end;

When the compiler reaches fMyClass, it knows that fMyClass is a pointer to
an object. That's all it really needs to know at that stage.

It seems to me that Delphi/Kylix could well have one pass parsers (even
though they may actually use multipass, I don't know), where parsing is the
first of several stages in a compilation.

Christen Fihl

oläst,
4 aug. 2003 04:03:512003-08-04
till
> PListNode = ^TListNode;

Even when TListNode could be of a known type already, it cannot be used
before the end to the current type block, as the type can be redefined.

Following program can, and should be able to compile in Pascal.

Program Test1;
type
tP = ^ Integer;
Integer=String;
var
P: tP;
begin
P:=....; // Initialize P to something
P^:='Correct';
// Cannot compile this! P^:=1;
end.


--
Christen Fihl
http://HSPascal.Fihl.net/

Peter Thönell

oläst,
4 aug. 2003 05:26:362003-08-04
till

> > PListNode = ^TListNode;
>
> Even when TListNode could be of a known type already, it cannot be used
> before the end to the current type block, as the type can be redefined.

Well... I tried the following now, and it worked fine. This is what we used
to do at uni. (I think before Turbo Pascal was released.)

type


PListNode = ^TListNode;
TListNode = record

Data: string;
Next: PListNode;
end;


> type
> tP = ^ Integer;
> Integer=String;

Eughh!!! =o ;)
I see your point. But normally one does not try to confuse the compiler.

Sebastian Moleski

oläst,
4 aug. 2003 09:07:332003-08-04
till
"Peter Thönell" <thon...@hotmail.com> wrote in message
news:3f2e02fe$1...@newsgroups.borland.com...

>
> > what reason that the object pascal did/do not allow forward reference?
> ...
> > your opinion?
>
> My opinion is that in a single pass compiler, the compiler must know what
> something is before it can accept it.
>
> ex.
> TMyRec = record
> int: integer; // it knows what this is
> SubRec: TSubRec; // but what is this?
> end;
>
> SubRec could be of any size. But old Pascal did allow this:
>
> PListNode = ^TListNode;
> TListNode = record
> Data: ....;
> Next: PListNode;
> end;

Delphi still allows that.

sm


Danny Thorpe

oläst,
4 aug. 2003 14:47:142003-08-04
till

"Peter Thönell" <thon...@hotmail.com> wrote in message
news:3f2e2708$1...@newsgroups.borland.com...

> Eughh!!! =o ;)
> I see your point. But normally one does not try to confuse the compiler.

The compiler would probably disagree with that claim. :P

-Danny


Brad White

oläst,
4 aug. 2003 18:49:122003-08-04
till
> > I see your point. But normally one does not try to confuse the
compiler.
>
> The compiler would probably disagree with that claim. :P
>
LOL.

Brad.


Bruce Roberts

oläst,
5 aug. 2003 15:48:592003-08-05
till

"Red Orchid" <redo...@invalid.invalid> wrote in message
news:3f2d...@newsgroups.borland.com...

> so far as i know,


> the modern language conception don't require 'forward declaration'.

I don't think one can characterize the fact that Delphi requires declaration
of a symbol before its use as an old-fashioned idea. The concept is, IMO,
integral to the concept of strong type checking and contributes to better
source layout.

Loren Pechtel

oläst,
6 aug. 2003 18:08:362003-08-06
till
On Tue, 5 Aug 2003 15:48:59 -0400, "Bruce Roberts" <b...@attcanada.net>
wrote:

>> so far as i know,
>> the modern language conception don't require 'forward declaration'.
>
>I don't think one can characterize the fact that Delphi requires declaration
>of a symbol before its use as an old-fashioned idea. The concept is, IMO,
>integral to the concept of strong type checking and contributes to better
>source layout.

Except when you are faced with a circular situation. I've
been forced to work around something that basically looks like:

Object A holds the various data pieces that comprise a job.
It also has the various forms that the user might use to create and
edit this job. Many of these editors are basically co-equal, there's
no boss. Yet they have to be able to transfer control to other
editors, or create ones that do not currently exist.

The existing forward system is fine for small stuff but this
comprises many modules. I ended up splitting A into an abstract
dispatcher (goto formXXXX), defining the forms all with no knowledge
of each other, and then finishing off A at the end.

0 nya meddelanden