AnyDAC is X * 100K lines complex library, utilizing Delphi Pascal / RTL / DB unit for 200%. Free Pascal Compiler (FPC) is free cross patform Pascal compiler, supporting also Delphi Pascal dialect. Lazarus is free cross platform IDE for FPC. And FCL is free cross platform component library, similar to VCL. Recently, in v 1.10.0, I have ported AnyDAC to FPC and FCL. As first step, I ported AnyDAC to FPC on Win32 platform. Later I will port to Linux. Beside the ability to use AnyDAC on this platform, I have found few things, where Delphi compiler may be improoved. First at all, I have got A LOT of warnings and hints compiling AnyDAC on FPC, many of them was very helpfull. But also FPC has some limitations and bugs. That is the list of things, I have found. 1. Hint: Unit "XXXX" are not in use. That great hint allows developer to clean up code and remove unused unit references. Delphi missed that. Although exists 3d party products, allowing to clean up USES clause. The best for me is PAL (http://www.peganza.com/). 2. Hint: Parameter "XXXX" not used. That may be good, but just for non virtual methods. When I got this hint on ALL of AnyDAC base classes abstract methods, I was a bit disappointed by FPC. How it knows, what for these params will be used in subclasses ?! 3. Hint: Type size mismatch, possible loss of data / range check error. These hints pointed me about 7 places of bugs ! And each of them is of hard-to-find kind. For example, few AnyDAC customers was reporting about incorrect sorting of rows by character fields. But nobody was able to reproduce this bug. But FPC generated "type size mismatch" hint for marked line of following code, comparing two string values: for i := 0 to iLen - 1 do begin >> iDiff := ShortInt((PChar(ABuff1) + i)^) - ShortInt((PChar(ABuff2) + i)^); if iDiff > 0 then begin Result := 1; Break; end else if iDiff < 0 then begin Result := -1; Break; end; end; Each of ShortInt((PChar(ABuff) + i)^) expressions may be in range -128..127. And resulting value may be in range -255..255, which is wider than ShortInt. But iDiff was declared as ShortInt ! Somehow, but Delphi there was silent ... 4. Warning: Class types "TCollection" and "TADFormatOptions" are not related. It was another hard-to-find error. AnyDAC has declarations: type TADMapRule = class(TCollectionItem) ....... procedure SetSourceDataType(Value: TADDataType); ....... end;
TADMapRules = class(TCollection) ....... FFormatOptions: TADFormatOptions; ....... end; TADFormatOptions = class(TADCustomOptions) ....... FMapRules: TADMapRules; ....... procedure CheckConversion(ASrc, ADest: TADDataType); ....... end; And there was code. I have marked line, where FPC generated hint. procedure TADMapRule.SetSourceDataType(Value: TADDataType); begin ....... >> TADFormatOptions(Collection).CheckConversion(Value, FTargetDataType); ....... end; But right code must be: procedure TADMapRule.SetSourceDataType(Value: TADDataType); begin ....... TADMapRules(Collection).FFormatOptions.CheckConversion(Value, FTargetDataType); ....... end; 5. "Range checking" exception is not raised in following case: type TADPhysRequest = (arNone, arFromRow, arSelect, arInsert, arUpdate, arDelete, arLock, arUnlock, arFetchRow, arUpdateHBlobs, arDeleteAll); TADPhysRequests = set of TADPhysRequest; TADPhysUpdateRequest = arInsert .. arDeleteAll; TADPhysUpdateRequests = set of TADPhysUpdateRequest; ....... var FGeneratedCommands: TADPhysUpdateRequests; ....... Exclude(FGeneratedCommands, arSelect); Include(FGeneratedCommands, arSelect); And AnyDAC behaviour was erroneous in some cases ... 6. FPC does not support "implements" keyword. So, interface delegation must be coded by hands. In most cases it is quite stupid and boring work ... 7. Comparision of two variant values of vtString and vtOleStr types will fail. So, put AnsiString and WideString into Variant, try compare them and you will get exception. 8. FPC RTL Format function does not support %:0s format specifiers. That means you cannot use the same value in few places of format string. 9. MultyReadExclusiveWriteSynchronize is really silly critical section. You may be really surprized, when your debugged multy threaded application will hang up ... 10. You will not believe, but FPC mixed each other two methods of one interface. So, when code calls one method, second method is called in reality. And backward. Nothing to say ... That is all. After resolving all these issues, I got AnyDAC working without any problems. |