_REDUCT Code Reduction Report

Top  Previous  Next

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

 

This report pinpoints unnecessary code that could be deleted, resulting in a smaller amount of code to maintain and search for errors.

 

__________________________________________________

 

Identifiers never used

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

 

This is a list of all identifiers that are declared but never used. The Delphi compiler (from Delphi 2) also reports this if warnings ($W+) have been turned on during compilation. Most often, you can remove these identifiers. If you remove any identifier, make sure your code still compiles and works properly. A wise habit is to first comment out these declarations, and remove them entirely when you have validated that the code still compiles and works as intended. Also, note that if a subprogram is not used, does not necessarily indicate that it is not needed at all. If it is part of a general unit, the subprogram could very well be used in other applications.

 

Identifiers (parameters, local variables etc) related to subprograms that are not used, are not reported.

 

Parameters to event handlers, or methods that are referenced in form files, are not reported as unused. The reason is to avoid too many unnecessary warnings.

 

Also unused methods of a class that are implemented through interfaces are not reported. In this case, the class has no choice but to implement these methods.

 

Example:

 

procedure TMyForm.mnuOpen(Sender : TObject);

begin

OpenFile;

end;

 

In this case, the parameter Sender is not reported as unused, since mnuOpen is an event handler.

 

This section is also generated for multi-projects.

__________________________________________________

 

Local identifiers only used at a lower scope

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

This is a list of all local identifiers that are only used at a lower scope, in nested subprograms. You can declare these identifiers in the local procedures/functions where they are actually used.

 

Example:

 

procedure Outer;

var

I : integer;

 

procedure Inner;

begin

   I := 55; // !! I is declared in Outer

   ..

end;

 

begin

..

end;

 

__________________________________________________

 

Local identifiers only used at a lower scope, but in more than one subprogram

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

This is a list of all local identifiers that are only used at a lower scope, in nested subprograms. You can probably declare these identifiers in the local procedures/functions where they are actually used, unless they should be shared by the nested subprograms.

 

Example:

 

procedure Outer;

var

I : integer;

 

procedure Inner1;

begin

   ..

   I := 55; // !! I is declared in Outer

   ..

end;

 

procedure Inner2;

begin

   ..

   I := 5;

   ..

end;

 

begin

..

end;

 

__________________________________________________

 

Local identifiers that are set and referenced once

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

This is a list of all local identifiers that are set and referenced just once. It may be more efficient to skip these intermediate identifiers.

 

Restrictions:

Identifiers that are first set as a var parameter in a call to a subprogram, and afterwards referenced are not reported.

 

Example:

 

procedure MyProc;

var

I : integer;

begin

I := Func(5);

..

 

if I = 5 then // !! if Func(5) = 5 then

begin

   ..

end;

end;

 

__________________________________________________

 

Local identifiers that possibly are set and referenced once

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

This is a list of all local identifiers that possibly are set and referenced just once. They are referenced in unknown fashion, and the parser cannot determine whether they are set or just referenced in these locations. It may be more efficient to skip this intermediate identifier.

 

Restrictions:

Identifiers that are first set as a var parameter in a call to a subprogram, and afterwards referenced are not reported.

 

Example:

 

procedure MyProc;

var

I : integer;

begin

I := Func(5);

..

UnknownProc(I); // !! UnknownProc(Func(5))

..

end;

 

__________________________________________________

 

Local identifiers that are set more than once without referencing in-between

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

This is a list of all local identifiers that are set (assigned) more than once without referencing in-between. You can probably remove all but the last assignment. It may of course also indicate a coding error.

 

Example:

 

procedure MyProc;

var

I : integer;

begin

I := 5;

..

I := 10; // !! I is set again

..

if I = 10 then

begin

   ..

end;

end;

 

__________________________________________________

 

Local identifiers that possibly are set more than once without referencing in-between

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

This is a list of all local identifiers that are set (assigned) more than once without referencing in-between. They are referenced in unknown fashion, and the parser cannot determine whether they are set or just referenced in these locations. You can probably delete all but the last assignment.

 

Example:

 

procedure MyProc;

var

I : integer;

begin

I := 5;

..

UnknownProc(I);

..

I := 10; // !! I may already be set

..

if I = 10 then

begin

   ..

end;

end;

 

__________________________________________________

 

Class fields that are zero-initialized in constructor

 

[D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

This is a list of all class fields that are zero-initialized in constructor. Since class fields are automatically zero-initialized when the object is created, there is usually no need to include this code.

 

Example:

 

type

TMyClass = class

private

   FInt : integer;

   FStr : string;

   FPtr : pointer;

public

   constructor Create; override;

   ..

end;  

 

constructor TMyClass.Create;

begin

   inherited Create;

   FInt := 0; // !! possibly unnecessary

   FStr := '';

   FPtr := nil;

end;

 

__________________________________________________

 

Class fields that possibly are zero-initialized in constructor

 

[D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

This is a list of all class fields that possibly are zero-initialized in constructor. They are referenced in unknown fashion, and the parser cannot determine whether they are set or just referenced in these locations. Since class fields are automatically zero-initialized when the object is created, there is usually no need to include this code.

 

Example:

 

type

TMyClass = class

private

   FInt : integer;

   FStr : string;

   FPtr : pointer;

public

   constructor Create; override;

end;  

 

constructor TMyClass.Create;

begin

   inherited Create;

   UnknownProc1(FInt); // !! possibly unnecessary

   UnknownProc2(FStr);

   UnknownProc3(FPtr);

end;

 

__________________________________________________

 

Local long strings that are initialized to empty string

 

[D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

This is a list of all local long strings that are initialized to empty strings. An unnecessary action, since long strings are automatically initialized as empty strings upon creation.

 

Example:

 

procedure MyProc;

var

S : string;

begin

S := ''; // !! unnecessary

..

end;

 

__________________________________________________

 

Local long strings that possibly are initialized to empty strings

 

[D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

This is a list of all local long strings that are initialized to empty strings. They are referenced in unknown fashion, and the parser cannot determine whether they are set or just referenced in these locations. An unnecessary action, since long strings are automatically initialized as empty strings upon creation.

 

Example:

 

procedure MyProc;

var

S : string;

begin

UnknownProc(S); // !! possibly unnecessary 

..

end;

 

__________________________________________________

 

Functions called only as procedures (result ignored)

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

These functions may possibly better be implemented as procedures, because the result is never used.

 

This section is also generated for multi-projects.

 

__________________________________________________

 

Functions/procedures (methods excluded) only called once

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

The code in these functions/procedures could possibly be included inline instead, avoiding an unnecessary call.

 

This section is also generated for multi-projects.

 

__________________________________________________

 

Methods only called once from other method of the same class

 

[BP7,D1,D2,D3,D4,D5,D6,D7,D8, D2005W, D2005N, D2006W, D2006N, D2007W]

These methods are never called from the outside. The code in these methods could possibly be included inline instead, avoiding an unnecessary call.

 

This section is also generated for multi-projects.

 

__________________________________________________

 

Unneeded boolean comparisons

 

This list contains locations with statements like

 

if bReady = true then

 

This could be shorter and better written as

 

if bReady then

 

 

__________________________________________________

 

Boolean assignment can be shortened

 

This list contains locations with statements like

 

if X then

Bool := true

else

Bool := false;

 

This could be shorter and better written as

 

Bool := X;

 

 

See also:

 

R_GEN General Reports