I was recently reading Raymond Chen’s blog The curse of the redefinition of the symbol HLOG. Although not exactly the same issue, it reminded me of a situation a coworker requested help on a long time ago.
The root of the issue was pretty simple, my colleague had the error E2037 Declaration of ‘SomeProc’ differs from previous declaration.
Now, most of the time, this is a pretty trivial error to correct. But I was initially baffled by the problem. Here’s what the declaration looked like :
type TSomeClass = class [...] Procedure SomeProc(ABitmap : TBitmap); [...] procedure TSomeClass.SomeProc(ABitmap : TBitmap); begin end;
Now, I don’t know about you, but the declarations look the same to me. It took me a few minutes to realize the source of the problem. Here’s what the fix looked like :
type TSomeClass = class [...] Procedure SomeProc(ABitmap : TBitmap); [...] procedure TSomeClass.SomeProc(ABitmap : Graphics.TBitmap); begin end;
Now, why was it required to use the full scope name in the function implementation? It so happens that, in the unit where the class was declared, the interface section had a use on Graphics.pas and the implementation had a use on Windows.pas. For this reason, TBitmap in the interface section was being interpreted as Graphics.TBitmap while TBitmap in the implementation section was interpreted as Windows.TBitmap.
Implicit scoping saves a lot of typing, especially now that Delphi uses doted namespace. I wouldn’t want to be required to type
Generics.Collections.TList<System.Classes.TAction> everytime I want to declare a list of TAction. That being said, like I mentioned recently, implicit behaviors can really reserve you surprises when you are not aware of them.