Recent

Author Topic: FPC feature request/suggestion  (Read 12076 times)

440bx

  • Hero Member
  • *****
  • Posts: 3944
FPC feature request/suggestion
« on: April 04, 2019, 07:51:12 am »
Hello,

Currently FPC supports the following:

1. var
2. out

I'd like to see a third way, specifically

3. inout

I think to lessen the burden on the developers, this feature could be implemented in two (2) stages:

1. make inout a synonym/alias for var.  This would allow a programmer to use the new keyword to make the program more "self documenting".

2. in some future release of the compiler, provide a full implementation which would entail the compiler making sure that the inout variable has been initialized before being passed as a parameter and output a warning if it has not.

Of course, if the developers do it in one shot, that would be great :)

I believe this would be a nice feature.  It would make programs that use it more self documenting and, it would also probably make future automatic translation of MS headers a bit simpler and more likely to be correct.

Thank you for reading.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Handoko

  • Hero Member
  • *****
  • Posts: 5129
  • My goal: build my own game engine using Lazarus
Re: FPC feature request/suggestion
« Reply #1 on: April 04, 2019, 09:04:29 am »
I'm okay with "var" but I agree "inout" is more self documenting.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: FPC feature request/suggestion
« Reply #2 on: April 04, 2019, 09:10:47 am »
Code: Pascal  [Select][+][-]
  1. {$macro on}{$define inout:=var}
  2. procedure test(inout value:integer);
  3. begin
  4. end;
  5. begin
  6. end.
But I find it syntax rot. The meaning of var is clear. OTOH, this macro does what you want.
« Last Edit: April 04, 2019, 09:18:53 am by Thaddy »
Specialize a type, not a var.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: FPC feature request/suggestion
« Reply #3 on: April 04, 2019, 09:14:15 am »
I believe this would be a nice feature.  It would make programs that use it more self documenting and, it would also probably make future automatic translation of MS headers a bit simpler and more likely to be correct.
I see no reason to add something like this. It complicates the language and adds a new keyword with no real gain.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: FPC feature request/suggestion
« Reply #4 on: April 04, 2019, 10:34:08 am »
I believe this would be a nice feature.  It would make programs that use it more self documenting and, it would also probably make future automatic translation of MS headers a bit simpler and more likely to be correct.
I see no reason to add something like this. It complicates the language and adds a new keyword with no real gain.
Here is the reason: if the compiler knows that the variable is inout then it can emit a hint (or warning) if an uninitialized variable is passed to the function or procedure.

There is another reason too: currently the -gt compiler switch incorrectly assumes that an out parameter is not initialized by the caller.  out is very clear, it tells the compiler that the variable will be written to in the function/procedure, it says absolutely nothing about the initialization state of the variable being passed to the function/procedure.

inout would provide a way for the compiler to help the programmer write better code and, it would also justify - the currently incorrect - assumption made by the -gt switch.

Code: Pascal  [Select][+][-]
  1. {$macro on}{$define inout:=var}
  2. procedure test(inout value:integer);
  3. begin
  4. end;
  5. begin
  6. end.
But I find it syntax rot. The meaning of var is clear. OTOH, this macro does what you want.

That macro causes the compiler to give a warning if the variable being passed to the function/procedure has not been initialized ?... what version of FPC are you using ?... that's a nice macro you got.

You're always entertaining :)
« Last Edit: April 04, 2019, 10:36:39 am by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: FPC feature request/suggestion
« Reply #5 on: April 05, 2019, 09:18:48 am »
I believe this would be a nice feature.  It would make programs that use it more self documenting and, it would also probably make future automatic translation of MS headers a bit simpler and more likely to be correct.
I see no reason to add something like this. It complicates the language and adds a new keyword with no real gain.
Here is the reason: if the compiler knows that the variable is inout then it can emit a hint (or warning) if an uninitialized variable is passed to the function or procedure.
This is done by var already. There is no reason to add a new keyword for something that already exists.

There is another reason too: currently the -gt compiler switch incorrectly assumes that an out parameter is not initialized by the caller.  out is very clear, it tells the compiler that the variable will be written to in the function/procedure, it says absolutely nothing about the initialization state of the variable being passed to the function/procedure.

inout would provide a way for the compiler to help the programmer write better code and, it would also justify - the currently incorrect - assumption made by the -gt switch.
Do you have an example for that? Cause it's a bit unclear what exactly you mean here...

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: FPC feature request/suggestion
« Reply #6 on: April 05, 2019, 01:54:36 pm »
This is done by var already. There is no reason to add a new keyword for something that already exists.
No.  It is not done by var already.

var cannot make any assumptions about the state, initialized or otherwise, of the variable being passed.  It simply tells the compiler to pass the variable by reference, that's all it does, absolutely nothing else.  var gives no information to the compiler as to the state of the variable, whether it must be initialized or not before using it is passed as a parameter.

out is the same as var with the addition that it informs the compiler that the variable will be written to in the function/procedure.   That additional information enables the compiler to emit a hint or warning if the out parameter isn't being written to.  IOW, it helps the programmer catch errors (it's nice to have a compiler's help in catching such easy to overlook details.)

The reason presented for not implementing inout isn't particularly solid (I'm being kind) because the same reason could have been used for not implementing out and constref for instance.  var already does what out and constref do (the argument you're presenting) but, in addition to that, they provide additional information to the compiler.  In the case of constref it informs the compiler that the variable, in spite of being passed by reference, is a read-only variable which enables the compiler to emit a warning or an error in the case of constref, if the programmer tries to write/modify the "constant".  It's nice to have the compiler's help to ensure the code doesn't do something that was not intended (which is what constref adds to var.)

inout would make it clear to the compiler that the variable being passed _must_ be initialized before passing it as a parameter.  This would enable the compiler to emit a hint/warning if the variable has not been initialized. IOW, the programmer is giving information to the compiler, which the compiler can use to warn the programmer he/she failed to initialize the variable.  Again, it's rather nice to have the compiler help the programmer ensure that the code is as it should be (which is why Pascal has strong typing, to help the programmer correct mistakes.)

There are good reasons why declarators such as "in", "out" and "inout" are being "synthesized" in C/C++ header declarations and, it is not because C/C++ programmers like to type.

And just for orthogonality. constref is a synonym for "in" (passing an uninitialized constref variable is rather likely to be a mistake.) out is already what its name says it is (the parameter will be modified/written to).  What's missing is a way to tell the compiler about parameters that are both in and out which var does not do, thereby letting the compiler know that the variable must be initialized before being used as a parameter _and_ written to in procedure/function.  If those two conditions are not met then, the compiler can emit a hint or a warning letting the programmer know that his/her usage of the variable is not as he/she declared it.

There is another reason too: currently the -gt compiler switch incorrectly assumes that an out parameter is not initialized by the caller.  out is very clear, it tells the compiler that the variable will be written to in the function/procedure, it says absolutely nothing about the initialization state of the variable being passed to the function/procedure.

inout would provide a way for the compiler to help the programmer write better code and, it would also justify - the currently incorrect - assumption made by the -gt switch.
Do you have an example for that? Cause it's a bit unclear what exactly you mean here...

There is an entire thread on the subject http://forum.lazarus.freepascal.org/index.php/topic,41857.0.html  -gt assumes that an out parameter has _not_ been initialized (by simply trashing it upon entry) an assumption which is completely unwarranted and incorrect, not to mention that it's supposed to trash local variables not parameters.   At least if there was an inout keyword, -gt could justify its behavior by noting that the programmer didn't specify the variable was initialized by specifying inout.

« Last Edit: April 05, 2019, 02:40:47 pm by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: FPC feature request/suggestion
« Reply #7 on: April 05, 2019, 02:08:09 pm »
Even if that is true (which is only so for older code), this can be handled with local switches so that if you use a VAR parameter under that define, the procedure signature gets the correct meaning of VAR for errorhandling.

I don't see ANY reason to make this yet another DIY incompatible syntax.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: FPC feature request/suggestion
« Reply #8 on: April 05, 2019, 02:18:21 pm »
Even if that is true (which is only so for older code), this can be handled with local switches so that if you use a VAR parameter under that define, the procedure signature gets the correct meaning of VAR for errorhandling.
I'm not seeing clearly what you mean there.  Can you give an example ?

I don't see ANY reason to make this yet another DIY incompatible syntax.
What would inout it be incompatible with ?   or are you thinking about something else ?
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: FPC feature request/suggestion
« Reply #9 on: April 05, 2019, 03:59:41 pm »
Even if that is true (which is only so for older code), this can be handled with local switches so that if you use a VAR parameter under that define, the procedure signature gets the correct meaning of VAR for errorhandling.
I'm not seeing clearly what you mean there.  Can you give an example ?

Code: [Select]
{$someswitchVAR VARISINOUT}

procedure xx (var yy:zz); // this signature gets mandatory in and output attributes for the static analyser.

Quote
I don't see ANY reason to make this yet another DIY incompatible syntax.
What would inout it be incompatible with ?   or are you thinking about something else ?

Delphi, $mode delphi, but more importantly I don't see the point and a language addition is an important thing.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: FPC feature request/suggestion
« Reply #10 on: April 05, 2019, 05:01:32 pm »
Code: [Select]
{$someswitchVAR VARISINOUT}

procedure xx (var yy:zz); // this signature gets mandatory in and output attributes for the static analyser.
are you suggesting changing the semantics of the var keyword by using a switch to turn into inout ?  A var is mandatory but, it doesn't tell the compiler anything about whether or not the variable should be initialized before passing it.  Adding semantics to "var" could definitely cause a lot of incompatibilities.  "var" should be left alone.

The point is to give more information to the compiler so the compiler can help the programmer ensure that the variable is used as it is intended. The cases are, 1. initialized and written-to - no way to tell the compiler at this time, 2. written-to, may or may not be initialized - done by out (a correct implementation, that is) and, 3. read-only, which implies it has been initialized, done by constref.

inout would complete the set of possibilities (case 1.) and warn when the programmer is passing a variable that has inadvertently not been initialized.  Currently the compiler cannot do that because it doesn't have enough information to do it.  That's what inout does. 


I don't see ANY reason to make this yet another DIY incompatible syntax.

What would inout it be incompatible with ?   or are you thinking about something else ?

Delphi, $mode delphi, but more importantly I don't see the point and a language addition is an important thing.
Don't include it in $mode Delphi.  It certainly wouldn't be the first time FPC has a feature that Delphi doesn't and, here is the point: inout is simply a mechanism for the programmer to inform the compiler that a variable should have been initialized before passing it as a parameter and that the variable's value will be changed in the called function/procedure.  Given that information the compiler can let the programmer know that he/she may have failed to initialize the variable before passing it (which neither var nor out are sufficient to determine that omission) and warn the programmer if he/she may have failed to set a value in the function/procedure (which var cannot do but out can - which is the whole reason to have added "out" to the language, it's its reason to exist.)  "inout" simply completes the set of possibilities.   I presume you can see the point now.

I agree that a language addition is an important thing, particularly those additions that help the compiler catch errors at compile time instead of runtime (such as inout).  A feature that often saves a lot of time to the programmer.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Kays

  • Hero Member
  • *****
  • Posts: 569
  • Whasup!?
    • KaiBurghardt.de
Re: FPC feature request/suggestion
« Reply #11 on: April 05, 2019, 05:38:45 pm »
[…] 3. inout […]
And I'd like to have the modifier
Code: Pascal  [Select][+][-]
  1. noInNoOut
a parameter you can't read from, nor write to.
Yours Sincerely
Kai Burghardt

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: FPC feature request/suggestion
« Reply #12 on: April 05, 2019, 07:33:48 pm »
Code: [Select]
{$someswitchVAR VARISINOUT}

procedure xx (var yy:zz); // this signature gets mandatory in and output attributes for the static analyser.
are you suggesting changing the semantics of the var keyword by using a switch to turn into inout ?  A var is mandatory but, it doesn't tell the compiler anything about whether or not the variable should be initialized before passing it. 

"VAR" is a token for read/write.  If for some reason you want to change semantics for warnings for some minor cases, that is the way to go.

Quote from: kay
noInNoOut

Why not directly add access control lists for every token  >:D

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: FPC feature request/suggestion
« Reply #13 on: April 05, 2019, 07:52:17 pm »
inout would make it clear to the compiler that the variable being passed _must_ be initialized before passing it as a parameter.  This would enable the compiler to emit a hint/warning if the variable has not been initialized.
But it already works with var:
Code: Pascal  [Select][+][-]
  1. procedure Test(var X: Integer);
  2. begin
  3.   X := 1;
  4. end;
  5.  
  6. var
  7.   Y: Integer;
  8. begin
  9.   Test(Y);
  10. end.
project1.lpr(9,9) Hint: Variable "Y" does not seem to be initialized

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: FPC feature request/suggestion
« Reply #14 on: April 05, 2019, 08:30:50 pm »
@Marco
"VAR" is a token for read/write.  If for some reason you want to change semantics for warnings for some minor cases, that is the way to go.
var is to tell the compiler that the variable should be passed by reference.  Nothing else.  At most, it could be construed to mean that the variable will be written to, which would actually not be correct, since passing by reference is often done for performance reasons (and also to prevent stack overflows), not to tell the compiler that the variable will be modified.

out does exactly the same thing as var, that is, pass by reference but, in addition to that, it lets the compiler know that the variable will be written to, which allows the compiler to check that it is actually written to and emit an error or warning if it is not.

constref is yet another case of something that does exactly the same thing as var, which is - again - pass by reference but, in addition to that, it lets the compiler know that the variable will _not_ be written to, which allows the compiler to generate an error if an attempt to write to it is made.

inout simply adds the case where the variable being passed _must_ (not optionally but, must) be initialized (the "in" part) and written to (the "out" part), which neither var, out nor constref do.   That would allow the compiler to give a warning if the variable isn't initialized thus helping the programmer to catch errors at compile time instead of run-time.

In all three cases, the code generated is exactly the same (leaving COM out of the picture).  What changes is the information given to the compiler so the compiler can help the programmer write correct code.   It's a mechanism to provide the compiler a way to verify that a variable is used as the programmer intended, just as "out" and "constref" are.

@Serge
But it already works with var:
Code: Pascal  [Select][+][-]
  1. procedure Test(var X: Integer);
  2. begin
  3.   X := 1;
  4. end;
  5.  
  6. var
  7.   Y: Integer;
  8. begin
  9.   Test(Y);
  10. end.
project1.lpr(9,9) Hint: Variable "Y" does not seem to be initialized
You are right, it does but, it really shouldn't.  There is no implication in the keyword "var" that a variable  should have been initialized (it often isn't and that is not an error.)  It really shouldn't generate a hint for that case and, generating it only contributes to drown really important hints in a large number of hints that are of little to no value.
« Last Edit: April 05, 2019, 09:02:16 pm by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018