8

I'm new in the Delphi programming scene and i have trouble calling a procedure in a procedure in my console application.

My simple application is for a item inventory running through a telnet server on windows. I'm using a old thinkpad as my thinclient running linux and a telnet client.

Using Delphi XE I've ran into a chicken or the egg situation.

I get addscreen undeclared indentifier... it is declared but under mainscreen !!! If i put addscreen procedure over the mainscreen one, any call to mainscreen in the addscreen procedure make me an error undeclared indentifier mainscreen!

In simple terms, how to make the procedure to be call everywhere in the program?

I've tried interface and implementation but its not valid in a console application program!

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, windows, messages, Console in 'Console.pas';


procedure mainscreen;
var
  choice: string;
begin
  clrscr;
  writeln(' ------------------------------------------------------------------------------------------------------------------------------');
  writeln(' |                                     Inventory Management 0.1 ALPHA                                                         |');
  writeln(' ------------------------------------------------------------------------------------------------------------------------------');
  writeln('');
  writeln('');
  writeln('');
  writeln('');
  writeln('');
  writeln(' Make a choice: Add(a), Remove(r), Edit(e), Backup Database(bd), Mass Add(ma), Mass Remove(mr)');
  writeln('?:');
  readln(choice);

  if choice = 'a' then 
    addscreen
  else 
    mainscreen;
end;

procedure addscreen;
var
  choice: string;
begin
  clrscr;
  writeln(' ------------------------------------------------------------------------------------------------------------------------------');
  writeln(' |                                                     Add an Item                                                            |');
  writeln(' ------------------------------------------------------------------------------------------------------------------------------');
  writeln('');
  writeln('');
  writeln('');
  writeln(' Not yet ready!');
  writeln(' Press any key to return to the main menu...');
  readln(choice);

  mainscreen;
end;

begin
  mainscreen;
  textbackground(black);
  textcolor(lightgray);
  ExitProcess(0);
end.

Thank you very much!

menjaraz
  • 7,551
  • 4
  • 41
  • 81
ELCouz
  • 572
  • 2
  • 6
  • 17
  • You would be better off moving the 'mainscreen' code into the 'main' program and moving more statements into the 'repeat' loop. – No'am Newman Oct 17 '11 at 05:58

1 Answers1

13

The compiler passes through the file from top to bottom. At the point where it needs to deal with the call to addscreen, you have not yet declared addscreen.

Since you have a circular reference (addscreen calls mainscreen and vice versa) you need to break that with what is known as a forward reference. Add this line before mainscreen

procedure addscreen; forward;

So the organisation of the code should look like this:

procedure addscreen; forward;

procedure mainscreen;
begin
  ...
end;

procedure addscreen;
begin
  ...
end;

If you did not have a circular reference then you could simply reorder the procedures so that the addscreen was declared before mainscreen.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 3
    Thank you! After many unsuccessful searches of Google, i finally get the right answer on stackoverflow! thank you very much! – ELCouz Oct 16 '11 at 19:52
  • 1
    And the next time you search for this question, you'll find Google listing your question and David's answer on stackoverflow. – lkessler Oct 16 '11 at 23:00
  • Circular reference may be not the best way to do it but it avoid the need of a loop in the main code. In fact main part is used only to call the first procedure then loop around in other procedure. Hard to read, spaghetti coding but it works! Thanks again ! – ELCouz Oct 16 '11 at 23:07
  • I didn't know the `forward` directive. I think it also works without it. Since when has this been there? – jpfollenius Oct 17 '11 at 08:53
  • @Smasher If A calls B and B calls A then you need forward directive. Perhaps you are thinking about methods of classes where the class declaration provides a forward declaration. The `forward` keyword has been present in Pascal since it was invented by Wirth. – David Heffernan Oct 17 '11 at 08:55
  • argh, you are right of course. I thought of class declarations. Does it work in this case also? It would indeed be more readable. – jpfollenius Oct 17 '11 at 09:01
  • @Smasher Not sure about adding `forward` to a class declaration. I'd guess that was a syntax error, but that's just a wild guess. It's never needed though which is why I guess that way. – David Heffernan Oct 17 '11 at 09:07
  • @Smasher, @David Heffernan: you don't need the `forward` keyword regarding class declarations. Forward class declarations are on the form `type className = class;`. See more on DocWiki, [Delphi Language Reference](http://docwiki.embarcadero.com/RADStudio/en/Classes_and_Objects) – Fabricio Araujo Oct 17 '11 at 17:48
  • @Fabricio Forward class declarations are a rather different topic. – David Heffernan Oct 17 '11 at 18:00
  • @DavidHeffernan: you mean `forward` in a *method* declaration? – Fabricio Araujo Oct 18 '11 at 17:12
  • @DavidHeffernan: if so, `forward` inside a class declarations it's a syntax error... – Fabricio Araujo Oct 19 '11 at 17:12