The Delphi Bug List

Entry No.
148
Compiler - Hints and Warnings
There are bugs in Delphi 2.0 and Delphi 3.0 that relate to the "localness" of the $HINTS and $WARNINGS directives. These directives do not have the same scope as other local directives like the $ALIGN directive.
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 4.03 5.0 5.01 6.0 6.01 6.02 Kylix 1.0
N/AExistsExistsExistsExistsExistsExistsExistsExistsExistsExistsExistsExistsExistsExists
Description
Reported by Hallvard Vassbotn; checked by Rune Moberg
The following three files demonstrate the problem:
LOCBUG.DPR:
program LocBug;
uses
  LocBugA;
begin
end.
LOCBUGA.PAS:
unit LocBugA;
interface
{$HINTS OFF} {$WARNINGS OFF} {$ALIGN OFF}
type
  TObjectA = class
  private
    UnusedA: integer;  // Should not get hint, and we don't
  public
    procedure Destroy; // Should not get warning, and we don't
  end;
  TRecA = record       // SizeOf(TRecA) should be 5, and it is
    A: char;
    L: longint;
  end;

implementation

uses
  LocBugB;
{.$HINTS OFF}      // Remove dots to work around the buggy behavior
{.$WARNINGS OFF}
type
  TObjectB = class
  private
    UnusedB: integer;  // Should not get hint, but we do in D3 (sometimes)
  public
    procedure Destroy; // Should not get warning, but we do (sometimes)
  end;
  {.$ALIGN ON}    // If you remove the dot, you will get an invalid typecast below
  TRecB = record  // SizeOf(TRecA) should be 5, and it is
    A: char;
    L: longint;
  end;
procedure TObjectA.Destroy; begin end;
procedure TObjectB.Destroy;
var
  A: TRecA;
begin
  TRecB(A).L := 123; // This is Ok because SizeOf(TRecA) = SizeOf(TRecB)
end;
end.
LOCBUGB.PAS:
unit LocBugB;
interface
implementation
{$HINTS ON} {$WARNINGS ON} {$ALIGN ON}
end.
The problem is that whenever the compiler re-compiles the LocBugB unit, the HINTS and WARNINGS are turned on and kept on from the point the unit is used in other units. The same does not happen with the ALIGN directive. So the "(sometimes)" in the comments above refers to whenever the LocBugB unit is re-compiled.

This means that to make sure HINTS and WARNINGS are turned off in a given unit you have to include {$HINTS OFF} and {$WARNINGS OFF} directives after the uses clause in the interface section _and_ after the uses clause in the implementation section.

This bug might seem innocent, but in combination with the very dangerous hints-bug I've written about before (it causes an access violation that forces you to close down D3), this new bug is very annoying. One of the suggested work-arounds for the first bug was to turn off hints for all code. This new bug means that this is not a simple task.

Solution / workaround
To make sure HINTS and WARNINGS are turned off in a given unit you have to include {$HINTS OFF} and {$WARNINGS OFF} directives after the uses clause in the interface section _and_ after the uses clause in the implementation section.

A related "bug" or short-coming

Often a unit needs to turn off hints and/or warnings for a small section of code. In the ideal case, this should be done without affecting the initial state of the HINTS directive. You would think that the $IFOPT directive could be used to achieve this, but that is not so. The $IFOPT directive only supports testing single-letter directives and there are no single letter variant of the HINTS and WARNINGS directives.

This means that you cannot write:

{$IFDEF _HINTS_ON_} Error: Define name clash! {$ENDIF}
{$IFOPT HINTS ON} {$HINTS OFF} {$DEFINE _HINTS_ON_} {$ENDIF}
...
{Hint-disabled code here}
{$IFDEF _HINTS_ON_} {$HINTS ON} {$UNDEF _HINTS_ON_} {$ENDIF}
This is admittedly ugly looking code, but it is the way we have handled local directives back to the TP/BP days. It would be very handy if Borland could add a pair of {$PUSHOPT} {$POPOPT} directives to help in this situations.

Another major shortcoming

The other work-around I suggested for the initial AV-generating hints bug was to use DCC32.EXE to compile the project. This is indeed possible, but it is an incredibly complicated, error-prone and manual process to get it working.

First of all, the Delphi IDE manages the project quite nicely and keeps all the options in the separate .DOF file. Why on earth can't DCC32 recognize and use this? Instead it insists on duplicating all the information in a DCC32.CFG file in the project directory (this makes it impossible to have more than one project in the same directory) or to give them all on the command line.

Secondly, it is awkward to start DCC32 from the Tools menu. To be able to see any error messages etc. you have to run it from a batch file. To run a batch file you have to run cmd/command and add /C DCC32.BAT to the parameters. Then you have to add $NAME($EXENAME) to give the name of the project file.

Latest update of this entry: 2002-04-03

Post a comment on this bug


Index page
Delphi Bug List home page
The Delphi Bug Lists are presently maintained by Jordan Russell, who has taken over this task from Reinier Sterkenburg since August 2000.
All feedback is appreciated. See also the feedback section of the Delphi Bug List home page.