Every couple of years, I'll stumble upon yet another Delphi compiler issue.
This time, here's the code that causes the problem.
program Project4; {$APPTYPE CONSOLE} {$R *.res} type IFather = interface procedure wait; cdecl; overload; procedure wait(millis: Int64); cdecl; overload; procedure wait(millis: Int64; nanos: Integer); cdecl; overload; end; ISon = interface(IFather) end; TSon = class(TInterfacedObject, ISon) procedure wait; cdecl; overload; procedure wait(millis: Int64); cdecl; overload; procedure wait(millis: Int64; nanos: Integer); cdecl; overload; end; { TSon } procedure TSon.wait; begin end; procedure TSon.wait(millis: Int64); begin end; procedure TSon.wait(millis: Int64; nanos: Integer); begin end; begin end.
After doing class completion so that method stubs are generated for the wait overloads, the fun begins after trying a compile. The full list of compile errors are as below:
I turn to the official documentation and there's no hint to what's wrong. I seem to remember Joe White stumbled upon some issues years ago and he mentioned that there were 2 types of directives, but the solution isn't there.
Eventually, by intuition, I figured out that the overload directive should appear first, and that's it! Rearranging all declarations as follows made the code compile!
type IFather = interface procedure wait; overload; cdecl; procedure wait(millis: Int64); overload; cdecl; procedure wait(millis: Int64; nanos: Integer); overload; cdecl; end; ISon = interface(IFather) end; TSon = class(TInterfacedObject, ISon) procedure wait; overload; cdecl; procedure wait(millis: Int64); overload; cdecl; procedure wait(millis: Int64; nanos: Integer); overload; cdecl; end;
In addition, removing the semicolon (;) from the original code works as well.
I filed a bug report and noted the 2 workarounds. Either remove the semicolon, or rearrange method directives so that overload appears first.
In 2017, with the release of Delphi 10.2 Tokyo, Embarcadero introduced a specialized implementation of the Observer pattern into the System.Classes unit. While it has been in the wild for 9 years, it remains a "hidden" architecture for many, primarily because it serves as the invisible engine behind LiveBindings. Other than live bindings, you can also use the Observer pattern as a way to update component settings to the Windows registry, an .ini file, or persist it elsewhere.
System.Classes