[ACCEPTED]-How does WriteLn() really work?-arguments

Accepted answer
Score: 26

Writeln is what we call a compiler "magic" function. If 9 you look in System.pas, you won't find a 8 Writeln that is declared anything like what 7 you would expect. The compiler literally 6 breaks it all down into individual calls 5 to various special runtime library functions.

In 4 short, there is no way to implement your 3 own version that does all the same things 2 as the built-in writeln without modifying 1 the compiler.

Score: 4

As the Allen said you can't write your own 10 function that does all the same things.

You 9 can, however, write a textfile driver that 8 does something custom and when use standard 7 Write(ln) to write to your textfile driver. We 6 did that in ye old DOS days :)

("Driver" in 5 the context of the previous statement is 4 just a piece of Pascal code that is hooked 3 into the system by switching a pointer in 2 the System unit IIRC. Been a long time since 1 I last used this trick.)

Score: 3

As far as I know, the pascal standards don't 17 include variable arguments.

Having said 16 that, IIRC, GNU Pascal let's you say something 15 like: Procecdure Foo(a: Integer; b: Integer; ...);

Try 14 searching in your compiler's language docs 13 for "Variable Argument Lists" or 12 "conformant arrays". Here's an 11 example of the later: http://www.gnu-pascal.de/demos/conformantdemo.pas.

As the prev poster 10 said, writeln() is magic. I think the problem 9 has to do with how the stack is assembled 8 in a pascal function, but it's been a real 7 long time since I've thought about where 6 things were on the stack :)

However, unless 5 you're writing the "writeln" function 4 (which is already written), you probably 3 don't need to implement a procedure with a variable 2 arguments. Try iteration or recursion instead 1 :)

Score: 3

It is magic compiler behaviour rather than 26 regular procedure. And no, there is no way 25 to write such subroutines (unfortunately!). Code 24 generation resolves count of actual parameters 23 and their types and translates to appropriate 22 RTL calls (eg. Str()) at compile time. This opposes 21 frequently suggested array of const (single variant array 20 formal parameter, actually) which leads 19 to doing the same at runtime. I'm finding 18 later approach clumsy, it impairs code readability 17 somewhat, and Bugland (Borland/Inprise/Codegear/Embarcadero/name 16 it) broke Code Insight for variant open 15 array constructors (yes, i do care, i use 14 OutputDebugString(PChar(Format('...', [...])))) and 13 code completion does not work properly (or 12 at all) there. So, closest possible way 11 to simulate magic behaviour is to declare 10 lot of overloaded subroutines (really lot 9 of them, one per specific formal parameter 8 type in the specific position). One could 7 call this a kludge too, but this is the 6 only way to get flexibility of variable 5 parameter list and can be hidden in the 4 separate module.

PS: i left out format specifiers 3 aside intentionally, because syntax doesn't 2 allow to semicolons use where Str(), Write() and Writeln() are 1 accepting them.

Score: 1

Yes, you can do it in Delphi and friends 12 (e.g. free pascal, Kylix, etc.) but not 11 in more "standard" pascals. Look up variant 10 open array parameters, which are used with 9 a syntax something like this:

procedure MyProc(args : array of const);

(it's been 8 a few years and I don't have manuals hand, so 7 check the details before proceeding). This 6 gives you an open array of TVarData (or something 5 like that) that you can extract RTTI from.

One 4 note though: I don't think you'll be able 3 to match the x:y formatting syntax (that 2 is special), and will probably have to go 1 with a slightly more verbose wrapper.

Score: 1

Most is already said, but I like to add 8 a few things.

First you can use the Format 7 function. It is great to convert almost 6 any kind of variable to string and control 5 its size. Although it has its flaws:

myvar := 1;
while myvar<10000 do begin
  Memo.Lines.Add(Format('(%3d)', [myVar]));
  myvar := myvar * 10;
end;

Produces:

(  1)
( 10)
(100)
(1000)

So 4 the size is the minimal size (just like 3 the :x:y construction).

To get a minimal 2 amount of variable arguments, you can work 1 with default parameters and overloaded functions:

procedure WriteSome(const A1: string; const A2: string = ''; const A3: string = '');

or

procedure WriteSome(const A1: string); overload;
procedure WriteSome(const A1: Integer); overload;
Score: 1

You cannot write your own write/writeln 15 in old Pascal. They are generated by the 14 compiler, formatting, justification, etc. That's 13 why some programmers like C language, even 12 the flexible standard functions e.g. printf, scanf, can 11 be implemented by any competent programmers.

You 10 can even create an identical printf function 9 for C if you are inclined to create something 8 more performant than the one implemented 7 by the C vendor. There's no magic trickery 6 in them, your code just need to "walk" the 5 variable arguments.

P.S.

But as MarkusQ have 4 pointed out, some variants of Pascal(Free 3 Pascal, Kylix, etc) can facilitate variable 2 arguments. I last tinker with Pascal, since 1 DOS days, Turbo Pascal 7.

Score: 1

Writeln is not "array of const" based, but 21 decomposed by the compiler into various 20 calls that convert the arguments to string 19 and then call the primitive writestring. The 18 "LN" is just a function that writes the 17 lineending as a string. (OS dependant). The 16 procedure variables (function pointers) for 15 the primitives are part of the file type 14 (Textrec/filerec), which is why they can 13 be customized. (e.g. AssignCrt in TP)

If 12 {$I+} mode is on, after each element, a 11 call to the iocheck function is made.

The 10 GPC construct made above is afaik the boundless 9 C open array. FPC (and afaik Delphi too) support 8 this too, but with different syntax.

procedure 7 somehting (a:array of const);cdecl;

will 6 be converted to be ABI compatible to C, printf 5 style. This means that the relevant function 4 (somehting in this case) can't get the number 3 of arguments, but must rely on formatstring 2 parsing. So this is something different 1 from array of const, which is safe.

Score: 1

Although not a direct answer to you question, I 13 would like to add the following comment: I 12 have recently rewritten some code using 11 Writeln(...) syntax into using a StringList, filling 10 the 'lines' with Format(...) and just plain 9 IntToStr(...), FloatToStr(...) functions 8 and the like.

The main reason for this change 7 was speed improvement. Using a StringList 6 and SaveFileTo is much, much more quicker 5 than the WriteLn, Write combination.

If 4 you are writing a program which creates 3 a lot of text files (I was working on a 2 web site creation program), this makes a 1 lot of difference.

More Related questions