Recent

Author Topic: Syntax proposals  (Read 12918 times)

damieiro

  • Full Member
  • ***
  • Posts: 200
Syntax proposals
« on: December 18, 2018, 03:31:07 pm »
Hi!

I'm newbie on this forum. So, sorry if not the correct place to put here the message
Where it can be posted syntax proposals?

Example:
Code: Pascal  [Select][+][-]
  1. {actual sintax without boilerplatecoding}
  2. Type
  3.   TMyclass=class;
  4. Var
  5.   MyClass:TMyClass;
  6.  
  7. begin
  8.   MyClass:=TMyClass.Create; {constructor}
  9.   {do things}
  10.   FreeAndNil (TMyClass);
  11. end;
  12.  

Proposed extended sintax:

Code: Pascal  [Select][+][-]
  1. {actual sintax without boilerplatecoding}
  2. Type
  3.   TMyclass=class;
  4. Var
  5.   MyClass:TMyClass;
  6.  
  7. begin
  8.   MyClass.Create;
  9.   {if Myclass is nil then call the constructor fully
  10.   and put it on MyClass ,
  11.   if not call only the method MyClass.create as usual}
  12.  
  13.   MyClass.Free;
  14. end;
  15.  

Proposed sintax 2:

Code: Pascal  [Select][+][-]
  1. {actual sintax without boilerplatecoding}
  2. Type
  3.   TMyclass=class;
  4. Var
  5.   MyClass: new TMyClass; {already made getmen for this in heap, not stack, so it points to a valid mem location}
  6.  
  7. begin
  8.   MyClass.Create; {would work, beause it's not nil}
  9.   MyClass.Free;
  10. end;
  11.  
« Last Edit: December 18, 2018, 03:32:44 pm by damieiro »

Thaddy

  • Hero Member
  • *****
  • Posts: 14214
  • Probably until I exterminate Putin.
Re: Syntax proposals
« Reply #1 on: December 18, 2018, 03:38:49 pm »
That all already exist. The FreeAndNil is a habit of some programmers to hide their own bugs, but generally many - if not all - expert programmers would advice against its use except under special circumstances.
Calling just free is alright - even better - in all but the borderline cases if the rest of your code is solid and well written.
Using FreeAndNil all over the place is in mnsho the hallmark of a programmer that doesn't know what his code is doing.... < expect some flames by those type of programmers: they should be ignored.
FreeAndNil can hide REAL bugs....>
If you are a beginner, just call free, if your code subsequently crashes, you made a mistake.

The second proposal is wrong altogether it works but has no reference so you can not actually use it because you don't know where it is?
It works in combination with the with statement, though....
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. begin
  3.   with TObject.Create do
  4.   try
  5.     writeln(Classname);
  6.   finally
  7.     free;
  8.   end;  
  9. end.code]
« Last Edit: December 18, 2018, 03:50:54 pm by Thaddy »
Specialize a type, not a var.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: Syntax proposals
« Reply #2 on: December 18, 2018, 04:02:52 pm »

Code: Pascal  [Select][+][-]
  1.   MyClass.Create;
  2.   {if Myclass is nil then call the constructor fully
  3.  

That has several problems.

1) It introduces huge potential for errors.

If MyClass is a local var, then it is not initialized and has a random value. So to fulfil the "is nil then call the constructor fully" condition you must write
Code: Pascal  [Select][+][-]
  1.   MyClass := nil;
  2.   MyClass.Create;
And there goes any gain you may have wanted.

Also if reading the code, the reader does often not know if   MyClass would be nil or not. So it would be unclear what it means.

2)
Code: Pascal  [Select][+][-]
  1.   MyClass.Create;
Already has a meaning. Changing it will/may break existing code.

It calls the constructor "Create" as a regular function.
And even if "MyClass" is nil, this is allowed.

This is valid code
Code: Pascal  [Select][+][-]
  1. TMyClass(nil).Create
assuming TMyClass.Create is written to deal with this.


garlar27

  • Hero Member
  • *****
  • Posts: 652
Re: Syntax proposals
« Reply #3 on: December 18, 2018, 05:29:48 pm »
[...]
FreeAndNil can hide REAL bugs....>
[...]
Never heard of that  :o
Can you explain how it hide some bugs?

Handoko

  • Hero Member
  • *****
  • Posts: 5132
  • My goal: build my own game engine using Lazarus
Re: Syntax proposals
« Reply #4 on: December 18, 2018, 05:34:32 pm »
I am not an expert in programming. But I almost never use FreeAndNil, and all my programs works correctly. I know on very rare cases only, FreeAndNil is needed.

Thaddy

  • Hero Member
  • *****
  • Posts: 14214
  • Probably until I exterminate Putin.
Re: Syntax proposals
« Reply #5 on: December 18, 2018, 05:41:59 pm »
[...]
FreeAndNil can hide REAL bugs....>
[...]
Never heard of that  :o
Can you explain how it hide some bugs?
https://community.idera.com/developer-tools/b/blog/posts/a-case-when-freeandnil-is-your-enemy
http://nickhodges.com/post/More-on-FreeAndNil.aspx

A simple real life example is to put destructors in the wrong order and possibly reference eachother. That would be caught by the compiler, but not with FreeAndNil - nil is a valid pointer reference! -. then you can have a use after free....
It is all pretty basic. The links are for Delphi but hold the same value for Freepascal.

Note that once a pointer is nil you also are not able to get a backtrace from it.... debugging is no option anymore....It is THAT silly. It is for bordercases and not for general programming.
To quote Nick Hodges:
"There are ways to code so that worrying about whether a pointer is valid or not is no longer something you have to worry about.  This way of coding is more productive, cleaner, and more effective.  It produces high-quality, testable code."
The blog by Allen Bauer - who actually wrote that code - is a heart felt scream not to miss-use it..
But programmers are lazy.....and often brainless.
« Last Edit: December 18, 2018, 06:18:54 pm by Thaddy »
Specialize a type, not a var.

Handoko

  • Hero Member
  • *****
  • Posts: 5132
  • My goal: build my own game engine using Lazarus
Re: Syntax proposals
« Reply #6 on: December 18, 2018, 05:57:49 pm »
I maybe wrong, but here I share my experience with FreeAndNil.

I remember clearly, I only use FreeAndNil once. Yes only once. Most programs will run correctly without using FreeAndNil. But I used it in a demo game I wrote. Writing games is is a challenging task. You add lots of 'spices' still you have to consider the balance between maintainability and code optimization.

The code I wrote generates and frees many objects runtime and perform several checking. Something like this:

If Assigned(TheObject) then PerformChecking;

The problem is the variable TheObject is a reusable variable and the object inside is generated and freed on other part of the code. Using assigned(TheObject) can't really detect if the object already freed. That's why I used FreeAndNil.

I wonder why people are so eager to use FreeAndNil, I do not see on other cases it is needed. Please correct me if I'm wrong.
« Last Edit: December 18, 2018, 05:59:22 pm by Handoko »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11384
  • FPC developer.
Re: Syntax proposals
« Reply #7 on: December 18, 2018, 05:57:54 pm »
Most importantly, the syntax

Code: Pascal  [Select][+][-]
  1. XXX.Create

already has well defined functionality in FPC and Delphi. Namely, call the constructor only on an already allocated and zeroed block of memory. (e.g. bulk memory instantiation)

Thaddy

  • Hero Member
  • *****
  • Posts: 14214
  • Probably until I exterminate Putin.
Re: Syntax proposals
« Reply #8 on: December 18, 2018, 06:10:57 pm »
I edited my post: I know those two people personally. Some of you know that.
Specialize a type, not a var.

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Syntax proposals
« Reply #9 on: December 18, 2018, 08:27:58 pm »
About for FreeAndNil.
Let's take a test example.
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$MODE OBJFPC}
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses SysUtils;
  6.  
  7. type
  8.   TParent = class;
  9.  
  10.   TChild = class(TObject)
  11.   strict private
  12.     FParent: TParent;
  13.   public
  14.     constructor Create(AParent: TParent);
  15.     destructor Destroy; override;
  16.   end;
  17.  
  18.   TParent = class(TObject)
  19.   strict private
  20.     FChild: TChild;
  21.   public
  22.     procedure ClearChild;
  23.     function GetChild: TChild;
  24.     destructor Destroy; override;
  25.   end;
  26.  
  27. procedure TParent.ClearChild;
  28. begin
  29.   Writeln('TParent.ClearChild');
  30.   //FChild.Free;
  31.   FreeAndNil(FChild);
  32. end;
  33.  
  34. destructor TParent.Destroy;
  35. begin
  36.   Writeln('TParent.Destroy');
  37.   ClearChild;
  38.   inherited;
  39. end;
  40.  
  41. function TParent.GetChild: TChild;
  42. begin
  43.   Writeln('TParent.GetChild');
  44.   if FChild = nil then
  45.     FChild := TChild.Create(Self);
  46.   Result := FChild;
  47. end;
  48.  
  49. constructor TChild.Create(AParent: TParent);
  50. begin
  51.   Writeln('TChild.Create');
  52.   inherited Create;
  53.   FParent := AParent;
  54. end;
  55.  
  56. destructor TChild.Destroy;
  57. begin
  58.   Writeln('TChild.Destroy');
  59.   if Assigned(FParent) then
  60.     FParent.ClearChild;
  61.   inherited;
  62. end;
  63.  
  64. var
  65.   Parent: TParent;
  66.   Child: TChild;
  67. begin
  68.   Parent := TParent.Create;
  69.   try
  70.     Child := Parent.GetChild;
  71.     if Assigned(Child) then
  72.       Writeln('OK');
  73.   finally
  74.     Parent.Free;
  75.   end;
  76.   Readln;
  77. end.
If you uncomment line 30 and comment out the 31st, there will be a runtime error.
Proponents of FreeAndNil argue that its use of code is more reliable.
Opponents of FreeAndNil argue that it hides logical errors.

My experience shows that it is better for beginners to use FreeAndNil. I myself prefer not to use it locally when an object is created and destroyed inside a block or procedure. But for global objects-use it.

Thaddy

  • Hero Member
  • *****
  • Posts: 14214
  • Probably until I exterminate Putin.
Re: Syntax proposals
« Reply #10 on: December 18, 2018, 08:36:55 pm »
My experience shows that it is better for beginners to use FreeAndNil. I myself prefer not to use it locally when an object is created and destroyed inside a block or procedure. But for global objects-use it.
So you encourage bad habits for noobs? Bad habits for experienced programmers are also not OK but at least they oversee the consequences of their errant ways... :o.
For global objects I also do not agree: use after free..... FreeAndNil hides that. If you need FreeAndNil on globals.... <ok, I throw a grumpy... >:D >:D >:D >
(That's only the fourth this year I believe.. :) :D ;D ;D )
« Last Edit: December 18, 2018, 08:40:18 pm by Thaddy »
Specialize a type, not a var.

garlar27

  • Hero Member
  • *****
  • Posts: 652
Re: Syntax proposals
« Reply #11 on: December 18, 2018, 08:43:32 pm »
I use FreeAndNil very often, sometimes I use it even when it's not needed. Mainly because of laziness and a little paranoid (bad combination).
Following is an imaginary example of all FreeAndNil types I use:
Code: Pascal  [Select][+][-]
  1.  
  2. procedure TMyClass.DoSomething(const AParam: string);
  3. var
  4.    TheWorker: TWorkerObject;
  5.    SomeAuxiliar: TAuxiliar;
  6. begin
  7.    TheWorker := nil;
  8.    SomeAuxiliar := nil;
  9.    TheWorker := TWorkerObject.Create;
  10.    try
  11.       FJob := TJob.Create;
  12.       Job.Load(AParam);
  13.       TheWorker.AssignJob(Job);
  14.       if TheWorker.NeedsAuxiliar then begin
  15.          SomeAuxiliar := TAuxiliar.Create;
  16.          SomeAuxiliar.SomeActions;
  17.       end;
  18.  
  19.       TheWorker.DoSomeWork;
  20.    finally
  21.       //TheWorker.Free;
  22.       FreeAndNil(TheWorker);// not needed, I know that and I'm not proud of it...
  23.       //if Assigned(SomeAuxiliar) then SomeAuxiliar.Free;
  24.       FreeAndNil(SomeAuxiliar);
  25.       //Job.Free;
  26.       //FJob := nil;
  27.       FreeAndNil(FJob);
  28.    end;
  29. end;
  30.  

I can't see which errors it can cause.

My experience shows that it is better for beginners to use FreeAndNil. I myself prefer not to use it locally when an object is created and destroyed inside a block or procedure. But for global objects-use it.
So you encourage bad habits for noobs? Bad habits for experienced programmers are also not OK but at least they oversee the consequences of their errant ways... :o.
For global objects I also do not agree: use after free..... FreeAndNil hides that. If you need FreeAndNil on globals.... <ok, I throw a grumpy... >:D >:D >:D >

Do you mean something like this:
Code: Pascal  [Select][+][-]
  1.    SomeObject.Free;
  2.    FreeAndNil(SomeObject); // Access Violation Here.
  3.  
Last time I did tried that code to see what happens raised an Access Violation in line 2 (tested on year 2008).

garlar27

  • Hero Member
  • *****
  • Posts: 652
Re: Syntax proposals
« Reply #12 on: December 18, 2018, 08:44:48 pm »
Shall we move the FreeAndNil thing to a different thread?  :-\

Thaddy

  • Hero Member
  • *****
  • Posts: 14214
  • Probably until I exterminate Putin.
Re: Syntax proposals
« Reply #13 on: December 18, 2018, 08:48:32 pm »
Shall we move the FreeAndNil thing to a different thread?  :-\
No need. We will shut up if you don't use it anymore. To paraphrase a song "Too much said, too much has been broken".
Specialize a type, not a var.

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Syntax proposals
« Reply #14 on: December 18, 2018, 08:56:31 pm »
Different thread already exists. It's ML thread from 2011: Difference between FreeThenNil and FreeAndNil - http://lists.lazarus.freepascal.org/pipermail/lazarus/2011-April/127647.html
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

 

TinyPortal © 2005-2018