FixInsight vs FMX in Delphi 10 Seattle

Several month ago I analyzed Delphi frameworks (VCL, FMX and RTL) with FixInsight and have found a number of interesting pieces of code. In this post I want to repeat my investigation and take a look at the latest FMX code in Delphi 10 Seattle Update 1 (23.0.21418.4207). As usual I will try to skip minor issues and mention only the most interesting parts of code.

W528 Variable ‘I’ not used in FOR-loop

for I := 0 to FContent.ControlsCount - 1 do begin Ctrl := FContent.Controls[Index]; if (Ctrl.Align = TAlignLayout.None) and ([TAnchorKind.akRight, TAnchorKind.akBottom] * Ctrl.Anchors <> []) and ControlList.TryGetValue(Ctrl, R) then begin // ...

This for-loop never uses ‘I’ variable. But it uses ‘Index’ instead (see line 558) which is a TFmxObject class property.

W528 Variable ‘J’ not used in FOR-loop

// Iterate through each control's list and remove gesture ID's // that don't exist in the updated FCustomGestures list for P in FControls do for I := P.Value.Count - 1 downto 0 do for J := 0 to FRecordedGestures.Count - 1 do begin if (P.Value[I].GestureType = TGestureType.Recorded) and (FRecordedGestures.FindGesture(P.Value[I].GestureID) = nil) then P.Value.Delete(I); end;

I have no idea what’s the purpose of this nested for-loop. Let me know if it’s a bug or not.

W511 Object ‘LinePath’ created in TRY block

for I := 0 to FFrame3D.Count - 1 do try LinePath := TPathData.Create; LLine := FFrame3D[I]; LineAdvance := 0; LineVerticalAdvance := 0;

No, it’s not that case when you set a variable to nil before a try block :)

W508 Variable is assigned twice successively

P := Content.LocalToAbsolute(BottomRight); P := AItem.ParentControl.AbsoluteToLocal(Content.LocalToAbsolute(BottomRight));

Not a bug actually, but is the first assignment really needed?

And one more:

Difference := []; Difference := Value - FInteractiveGestures;

Now bad news.

Unfortunately some of the issues I have reported last time were not fixed. So I have to repeat and update.

W517 Variable ‘Color’ hides a class field, method or property

procedure TLight.ReadDiffuse(Reader: TReader); var Color: Integer; begin IdentToAlphaColor(Reader.ReadIdent, Color); {$R-} Color := TAlphaColor(Color); {$R+} end;

Variable ‘Color’ hides the TLight.Color property. So I think line 2759 should be “Self.Color := TAlphaColor(Color);”

And the same again:

procedure TStrokeCube.ReadMaterialDiffuse(Reader: TReader); var Color: Integer; begin IdentToAlphaColor(Reader.ReadIdent, Color); {$R-} Color := TAlphaColor(Color); {$R+} end;

W508 Variable is assigned twice successively

FPixelShader := TShaderManager.RegisterShaderFromData('gouraud.fps', TContextShaderKind.PixelShader, '', [ TContextShaderSource.Create(TContextShaderArch.DX9, [ $00, $02, $FF, $FF, $FE, $FF, $32, $00, $43, $54, $41, $42, $1C, $00, $00, $00, $9F, $00, $00, $00, $00, $02, $FF, $FF, $03, $00, $00, $00, $1C, $00, $00, $00, $00, $01, $00, $20, $98, $00, $00, $00, // skipped

FPixelShader := TShaderManager.RegisterShaderFromData('gouraud.fps', TContextShaderKind.PixelShader, '', [ TContextShaderSource.Create(TContextShaderArch.DX9, [ $00, $02, $FF, $FF, $FE, $FF, $32, $00, $43, $54, $41, $42, $1C, $00, $00, $00, $9F, $00, $00, $00, $00, $02, $FF, $FF, $03, $00, $00, $00, $1C, $00, $00, $00, $00, $01, $00, $20, $98, $00, $00, $00, // skipped

Two assignments in a row, probably not an issue, just a sloppy copy-paste.

W503 Assignment right hand side is equal to its left hand side

if X1 > X2 then X1 := X1; if Y1 > Y2 then Y1 := Y2;

I guess, it should be “X1 := X2”.

if (Self.Form <> nil) and (Self.Form.Handle <> nil) then Self.Form := Self.Form;

Not sure what was meant to be there (Self.Form is a record field).

And one more.

if FNew.FFrequency <> 0 then FNew.FValue := Round(FNew.FValue / FNew.FFrequency) * FNew.FFrequency else FNew.FValue := FNew.FValue;

W510 Values on both sides of the operator are equal

if RegionSize = RegionSize then begin SetLength(UpdateRects, RegionData.rdh.nCount); for i := 0 to RegionData.rdh.nCount - 1 do begin R := PRgnRects(@RegionData.buffer[0])[i]; UpdateRects[i] := RectF(R.Left, R.Top, R.Right, R.Bottom); end; end;

Not sure what was meant to be there. The same code in FMX.Platform.Win.Style.pas

if RegionSize = RegionSize then begin SetLength(UpdateRects, RegionData.rdh.nCount); for I := 0 to RegionData.rdh.nCount - 1 do begin R := PRgnRects(@RegionData.buffer[0])[I]; UpdateRects[I] := RectF(R.Left, R.Top, R.Right, R.Bottom); end; end;

Copy and paste?

W513 Format parameter count mismatch

function TCustomValueRange.GetNamePath: string; begin Result := Format( 'Value: %0:*.*f (%1:*.*f..%2:*.*f)', [Value, Min, Max]); end;

The format string is incorrect. This code will raise an exception if you try to execute it.

W505 Empty THEN block

if FoundValue.Count > 1 then else if FoundValue.Count > 0 then PropValues[Name] := FoundValue[0];

This looks strange, perhaps it could be replaced with a simple “If FoundValue.Count = 1 then PropValues[Name] := FoundValue[0]”.

That’s all. A good reason to use FixInsight, isn’t it? :)