Thursday, March 20, 2008

What is wrong with this code?

unit Unit3;

interface

uses
Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm3
= class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure MyFunction(x : string);
end;

var
Form3: TForm3;

implementation

{$R *.dfm}
procedure TForm3.Button1Click;
begin
MyFunction(
'test')
end;

procedure TForm3.MyFunction;
begin
ShowMessage(x);
end;

end.

Well after using Delphi for more then a decade I would say that this code would not compile because of the fact that both MyFunction and Button1Click misses their parameterlist in the implementation section.


But in fact it is perfect Delphi code as it compiles without a problem!


Never, ever I have seen code like this before, until today in a project that I do maintenance for.


Don't try this at home, because it makes,imo, your code a nightmare to read.

9 comments:

Andreas Hausladen said...

This feature was introduced with TurboPASCAL 5 (or was it 5.5).

Anonymous said...

In a previous version of delphi, it did not even care if the implementation of the code used procedure/fuction, just that it used one or the other - it just ignored it instead of comparaing it to the declaration.

Fortunately, enough bitching was able to get them to see the error of their ways (it was not initially seen as a problem by Borland at the time).

Yes, this ability to not have to redeclare 100% accurately (and it is VERY flexible in what you can leave out sadly) creates a maintainability nightmare.

Anonymous said...

Funny! I did not know that!

Anonymous said...

personally, I find it annoying that I type this in the class:
procedure test(b: Boolean = true);

call code completion with Ctrl-Shift-C

and it puts this:
procedure TForm1.test(b: Boolean);
begin

end;

I have to look at the class declaration to see the default parameter, or add it myself to the procedure declaration.

gabr said...

Personally, I'm very happy that class completion works that way.

I'm using ModelMaker Code Explorer a lot and it adds default values to the implementation section, too, and I hate that.

In my opinion, default values are only part of the contract between the method and its callers and by that they only belong in the interface section.

Implementation section should implement the code without the special knowledge of what is default and what not - the code should work correctly in all cases.

Robin said...

Wow! I can't believe that works!

You learn something every day...

Lex Y. Li said...

I guess this trick fails when you have overloading functions.

Anonymous said...

It has been there for a long time. I myself have left out parameters while doing a quick project/prototypes.

xSpiky said...

This is better (Delphi 5 compile)

program Project1;

procedure test(sParam:string; sParam2:string = '');
begin

end;

begin
test('wtf',); // -see comma
end.