Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Compiler/Delphi/RTTI    [ Add a report in this area ]  
Report #:  79943   Status: Closed
{$RTTI} Flag scope
Project:  Delphi Build #:  14.0.3513.24210
Version:    14.0 Submitted By:   Éric Fleming Bonilha
Report Type:  Crash / Data loss / Total failure Date Reported:  12/1/2009 11:09:05 AM
Severity:    Commonly encountered problem Last Updated: 4/15/2014 6:50:21 PM
Platform:    All platforms Internal Tracking #:   13886
Resolution: Fixed (Resolution Comments) Resolved in Build: : XE6
Duplicate of:  None
Voting and Rating
Overall Rating: (2 Total Ratings)
5.00 out of 5
Total Votes: 54
Description
[JJS]
If the user declares {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} in the first beginning of my project (Eg. in my dpr file just before the uses section) the extended RTTI is disabled for ALL units of the project.

It seams that the compiler is keeping the {$RTTI}
parameters upon unit expansion (getting out of the scope of a single unit) after it first finds it, so for example if I have a program like this with 3 units and the units has the uses sections like this:

Unit1:
uses
  Unit2;


Unit2
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
uses
  Unit3;


Unit3
...


Than, the RTTI is disabled for both Unit2 and Unit3 but not for Unit1, so, it seams that it is keeping the {$RTTI} parameters when it expands through the units
Steps to Reproduce:
- Create a new project
- Create 3 new units called Unit1, Unit2, Unit3

In unit1, reference the unit2 (From the implementation) and create a test record (For extended RTTI testing):

unit Unit1;

interface

type

  TMyTypeUnit1 = record
    Field1: string;
    Field2: string;
  end;

implementation

uses
  Unit2;

end.



In unit2:

unit Unit2;

interface

{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}

uses
  Unit3;

type

  TMyTypeUnit2 = record
    Field1: string;
    Field2: string;
  end;

implementation

end.


In unit3:

unit Unit3;

interface


type

  TMyTypeUnit3 = record
    Field1: string;
    Field2: string;
  end;

implementation

end.




Now, test the RTTI with the following routine

procedure TForm1.Button1Click(Sender: TObject);
var
  RttiContext: TRttiContext;
  RttiRecordType: TRttiRecordType;
begin

  // Get the context
  RttiContext := TRttiContext.Create;

  // TMyTypeUnit1
  RttiRecordType := TRttiRecordType(RttiContext.GetType(TypeInfo(TMyTypeUnit1)));
  ShowMessage(IntToStr(Length(RttiRecordType.GetFields)));

  // TMyTypeUnit2
  RttiRecordType := TRttiRecordType(RttiContext.GetType(TypeInfo(TMyTypeUnit2)));
  ShowMessage(IntToStr(Length(RttiRecordType.GetFields)));

  // TMyTypeUnit3
  RttiRecordType := TRttiRecordType(RttiContext.GetType(TypeInfo(TMyTypeUnit3)));
  ShowMessage(IntToStr(Length(RttiRecordType.GetFields)));

end;


You will notice that TMyTypeUnit1 will return 2 Fields wich is correct

TMyTypeUnit2 should return 0 fields because I disabled the extended RTTI information JUST FOR UNIT2 by declaring the {$RTTI} directive in Unit2

BUT... TMyTypeUnit3 WILL ALSO RETURN 0!!! Even without the {$RTTI} Directive in Unit3

And the most problematic

if I declare the {$RTTI} Directive in my dpr, the RTTI will be disabled for ALL UNITS!!!

program Project1;

{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
Workarounds
None
Attachment
RTTI Fail.zip
Comments

Ralf Stocker at 12/28/2009 8:24:20 AM -
I would prefer a global compiler switch that affects all sources.

Éric Fleming Bonilha at 1/8/2010 7:46:35 PM -
Me too, but I don´t think that this was the idea of the {$RTTI} implementation, but a global compiler would be usefull, but this can raise some problems like what if you use a library of components that require some kind of RTTI information and you disable all globally?

Server Response from: ETNACODE01