Inlining a public function requires everything it access to be public

Let’s consider this code:

type
  TMyClass = class
  private
    FStrings: List<string>;
  public
    method Lock; empty;
    method Unlock; empty;

    function GetString(AIndex: Integer): string; inline;
    begin
      Lock;
      try
        Result := FStrings[AIndex];
      finally
        Unlock;
      end;
    end;
  end;

Under Delphi, the inline keyword is quite happily used but with Oxygene, I get an error message at the very end of the compilation telling me that FStrings is private and thus GetString cannot be inlined.
Why is there such a limit here?

Well. inlined code runs in the context of the caller. if an inline function of class A accesses a private field and that code gets inlined into a method in class B, its as if you had written that code right there, in class B. and class B literally has no access to the private field.

Yes, I know how inlining works, but in Delphi it works just fine because the compiler know the offset of the private field and can calculate the appropriate address to access at the location where the code is expanded.
Granted, this might not be possible for all platforms that Oygene is targeting, but in this case, I believe this should really be a warning, not an error.

Yeah, but in the case ofd .NET, the runtime will, literally, not let you access the field. there’s nothing we can do.

Indeed, we could fix this for Island and (possibly) Toffee, but this won’t do you any good ;). For .NET, we’re stuck with this, sorry :(.

Then could it at least be changed to a warning saying “Sorry, impossible to inline this”?
I mean, in Delphi, the inline keyword is only a suggestion anyway.

Oh, you meant like this. yeah, I think we can do that, for Delphi Compatibility Mode.

Thanks, logged as bugs://84748

Until then: what happens when you turn off inlining in project settings? does it still err on things that can’t be inlined? maybe the compiler already just ignores the inline keyword without further checks then?

I had not tried that, but I still get the error message any way. So my initial solution of IFDEFing it out is still valid.

1 Like

I guess we should turn the error off for that case, too.

1 Like

bugs://84748 got closed with status fixed.

bugs://84748 got reopened. (sorry, fix introduced a regression so I had to revert it; —mh)

bugs://84748 got closed with status fixed.