Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it always safe to remove a published empty section?

I'm working on an old legacy project which have several classes in which the published section is always declared without anything inside of it, i.e:

TMyClass = class
public
   procedure DoSomething();
published
end;

On compiling, I get the following warning message:

[DCC Warning] uMyUnit.pas(141): W1055 PUBLISHED caused RTTI ($M+) to be added to type 'TMyClass'

I don't know if the predecessor developer has declared these published sections for some valid reason. Is it always safe to remove an empty published section or could it cause some changes in the application's behavior?

like image 531
Fabrizio Avatar asked Sep 03 '19 14:09

Fabrizio


2 Answers

The difference for the class itself is none - however the important thing is that the default visibility of any class that inherits from a class with {$M+} then changes from public to published!

See this example code:

uses
  TypInfo;

type
  TMyClass = class
  private
    fName: string;
    property Name: string read fName;
  published
  end;

  TMyOtherClass = class(TMyClass)
    property Name;
  end;

var
  propCount, i: Integer;
  props: PPropList;
begin
  propCount := GetPropList(TypeInfo(TMyOtherClass), props);
  for i := 0 to propcount - 1 do
    Writeln(props^[i].Name);
  Readln;
end.

You can see that it lists the Name property but when you remove the published from TMyClass it will not - that is because once TMyClass got {$M+} added any member declared without explicitly stating the visibility it will be published opposed to public.

Also other members declared without visibility like fields will be published. This is being used in the streaming system Delphi uses for forms and such. You can for example then call TObject.FieldAddress or TObject.MethodAddress passing in the name of a field or method and get back pointers to the field or method. It only works with published fields and methods.

This is how loading from a dfm sets up all those IDE generated fields like Button1 or connects the Button1Click method to the Button1.OnClick - they are without explicit visibility at the top of your form which inherits from TComponent that has {$M+} declared.

like image 95
Stefan Glienke Avatar answered Nov 11 '22 13:11

Stefan Glienke


It depends

Does the rest of the code actually require access to RTTI for the class?

Only TPersistent-derived classes have the {$M+} directlive applied to them by default without needing a published section.

A published section is used for DFM streaming, which requires RTTI. Non-persistent classes are not steamed in DFMs, but there are other uses for RTTI.

So, without knowing what the rest of the code does, it is not really known whether removing empty published sections is safe or not.

like image 3
Remy Lebeau Avatar answered Nov 11 '22 11:11

Remy Lebeau