Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2018-08

Re: Little question about the

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

J. Gareth Moreton

Thanks Sven,
Sorry if I'm bringing up obvious points.  I've set "pure" to be interface-only - it's a little tricky because if you now specify it in the main source file, it says that it can't be used in the implementation section, even though, really, the main file doesn't have such section.  Still, that can be dealt with.
This will require a lot of testing once I start submitting patches!

Gareth aka. Kit

On Fri 10/08/18 06:45 , "Sven Barth" sent:
Gareth sent me the following two mails in private, but they were ment for the list:

J. Gareth Moreton wrote 17 lines
Thanks Sven. Normally I would agree with "pure" only belonging in the interface section, but it causes problems when you try to put a pure function inside the main program block, as the entire thing is considered equivalent to implementation. Also, inline is allowed in the implementation section, and the two follow similar rules in regards to their calls being modified. Just to clarify, "pure" doesn't change anything in regards to the parameter types or how a call with variable arguments is handled. The raw signature shouldn't change. It's an optimisation hint. At least it is in a perfect world!
J. Gareth Moreton wrote 41 lines
I asked the question because I stumbled across something interesting.  I've been using the following set of functions to see how the compiler handles things that are a bit out of order (using 'inline' as a temporary stand-in): program PureTest; function PureMax(const a: Double; const b: Double): Double; forward; procedure TestFunc; begin   WriteLn(PureMax(2.0, 3.0)); end; function PureMax(const a: Double; const b: Double): Double; inline; begin   if (a > b) then     Result := a   else     Result := b; end; begin   TestFunc; end. **** Turns out, to my surprise, after analysing the nodes and the disassembly, that "PureMax" is not inlined inside the TestFunc routine.  I haven't tested units yet, but would a similar situation occur if a function is not defined as inline in the "interface" section and only the "implementation" section (unless the caller appears after said function in the source file)? Either way, I'm leaning towards making the new "pure" directive an interface-only directive as Sven suggested, as that will make things a lot easier if a pure function is used as part of a constant definition.  After all, "pure" would have a bit more of a notable effect than "inline" because it dictates where the function can and cannot be used.

I hadn't thought that I need to explain that, but apparantly you haven't yet reached that far in your research of the compiler, so:
- of course I only mean that it's an interface-only modifier if there *is* an interface section; routines that are - inside a unit - only declared inside the implementation section are obviously exempt from this (thus also for the program file)
- again I wrote that I don't mean that "pure" modifies the parameters, but it modifies the meta data (most importantly checksum) of the interface section when you add a modifier flag inside the implementation section. The compiler first handles the interface sections of units and might then compile interface sections or even implementation sections of other units depending on the dependencies between the units. If a flag only appears in the implementation section than this messes up this whole thing as the other units would need to be recompiled. This is already a mess with "inline" so we don't need to do that with "pure" as well, especially as we don't need to be Delphi compatible here.
- yes, it is correct that the compiler's capability to inline depends on the order of the routine definitions. The compiler generates the code routine by routine so if the routine's body has not yet been encountered then it can't be inlined. (When using generic specializations it triggeres the generation of the specialized routine bodies before generating the routine to avoid "inline" not working for generics) For "pure" we can even go so far as to say that a routine body *must* be available to be able to call it inside another "pure" routine. Everything else would be an error.

I hope this clears things up a bit.

Regards,
Sven

Reply by email

Sven Barth
to J. Gareth Moreton

J. Gareth Moreton schrieb am Fr., 10. Aug.
2018, 18:44:

Show quoted text 8 lines
Thanks Sven, Sorry if I'm bringing up obvious points. I've set "pure" to be interface-only - it's a little tricky because if you now specify it in the main source file, it says that it can't be used in the implementation section, even though, really, the main file doesn't have such section. Still, that can be dealt with.

You shouldn't declare it as interface only, but you should disallow the situation that it is not set for the forward def in the interface, but for the one in the implementation section. Other combinations are valid. I think the function to look for is add_proc_definition (can't check currently).
Also the defs should contain methods to check whether they had been declared in the interface or implementation section so you can use those.

Regards,
Sven

Reply by email

J. Gareth Moreton

Sorry for not quite understanding what you mean.  Are you meaning that if I detect something like this in the main file...

 ****
 program SomeProg;
 function PureFunc(A: Integer): Integer; forward;
 procedure TestFunc;
 begin  { Call PureFunc }
 end;
 function PureFunc(A: Integer): Integer; pure;
 begin
   { etc. }
 end;
 ****

... an error should be thrown?  But if something like this appears:

 ****
 unit SomeUnit;
 interface
 function PureFunc(A: Integer): Integer;
 implementation
 procedure TestFunc;
 begin  { Call PureFunc }
 end;
 function PureFunc(A: Integer): Integer; pure;
 begin
   { etc. }
 end;
 ****

... all is well?  Is it only problematic if a function is defined as "forward" and not "pure" on the same line?

Gareth aka. Kit

On Fri 10/08/18 19:51 , "Sven Barth" sent:
J. Gareth Moreton schrieb am Fr., 10. Aug. 2018, 18:44: Thanks Sven,
Sorry if I'm bringing up obvious points.  I've set "pure" to be interface-only - it's a little tricky because if you now specify it in the main source file, it says that it can't be used in the implementation section, even though, really, the main file doesn't have such section.  Still, that can be dealt with.
You shouldn't declare it as interface only, but you should disallow the situation that it is not set for the forward def in the interface, but for the one in the implementation section. Other combinations are valid.  I think the function to look for is add_proc_definition (can't check currently). Also the defs should contain methods to check whether they had been declared in the interface or implementation section so you can use those. 
Regards, Sven 

Reply by email