Jump to content
PeterPanettone

Initialize local variables at declaration

Recommended Posts

While this is possible:

image.png.d2b6b0de9ebe454d5c9b884f37acb004.png

This is currently not possible:

image.png.5e7fe3b329868907022225fcbaffcde9.png

 

However, this would be a big time-saver and would make the code more compact and easier to read.

 

What do you people think?

Share this post


Link to post
Posted (edited)

This was implemented 10.3 via inline variables. It however is not possible to declare the variable in the old way plus initialize it - you have to declare it inline:

procedure DoSomething;
begin
  var MyVar: Integer = 23;
  //
end;

You can even omit the type there and it will automatically be Integer:

procedure DoSomething;
begin
  var MyVar = 23;
  //
end;

See http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html

Edited by Stefan Glienke
  • Thanks 1

Share this post


Link to post

Thanks, Stefan.

 

I would have preferred "the old way" which is more formal.

 

BTW, are there any drawbacks in using inline variables? I am not sure, but I remember having read somewhere that there is still a bug in using inline variables.

Share this post


Link to post

IDE tooling does not work properly and some of it completely stops,

Also inline variables of a managed type are not always properly initialized.

 

As much as I like this feature syntax wise - I would stay away from it for now 😞

  • Like 5

Share this post


Link to post
27 minutes ago, Stefan Glienke said:

IDE tooling does not work properly and some of it completely stops,

Also inline variables of a managed type are not always properly initialized.

 

As much as I like this feature syntax wise - I would stay away from it for now 😞

If everyone stays away, bugs will never be found and fixed...

 

I have used them a lot in various shorter and longer experimental code... so far so good (in spite known bugs)

  • Like 1

Share this post


Link to post
18 minutes ago, Dalija Prasnikar said:

found and fixed

Those are two different things, but using your release to beta test your tool set isn't really for everyone..

 

Share this post


Link to post

Well, if Editor marks inline variables as error is the only bug caused by inline variables then I can easily live with it as I have switched Error insight off:

 

image.thumb.png.a21e71b334f1233d6cabcfc23356885a.png

 

Or are there any other bugs caused by inline variables?

Share this post


Link to post
Posted (edited)
25 minutes ago, PeterPanettone said:

any other bugs

Stefan's link shows 75 bugs.. then there are those 'secret' internal ones..

Edited by FredS

Share this post


Link to post
2 hours ago, Dalija Prasnikar said:

If everyone stays away, bugs will never be found and fixed...

Herd immunity springs to mind

  • Haha 1

Share this post


Link to post
On 4/1/2019 at 7:25 AM, Stefan Glienke said:

It however is not possible to declare the variable in the old way plus initialize it - you have to declare it inline

Note that FreePascal supports initializing variables in "old style" declarations.  A shame that Delphi does not also support that, seems like something that might have been easy for Embarcadero to add while they were messing around with how variable declarations work.

Share this post


Link to post
4 hours ago, Remy Lebeau said:

Note that FreePascal supports initializing variables in "old style" declarations.  A shame that Delphi does not also support that, seems like something that might have been easy for Embarcadero to add while they were messing around with how variable declarations work.

Is there a specific technical reason why FreePascal can do it and Delphi can't do it?

Share this post


Link to post
1 hour ago, PeterPanettone said:

Is there a specific technical reason why FreePascal can do it and Delphi can't do it?

There is no technical reason that I can think of, Borland/CodeGear/Embarcadero could have expanded on the Pascal syntax, like FreePascal did, but they simply never got around to implementing it that way.  Remember that FreePascal is its own Pascal compiler, it is not based on Delphi, so it is free to do things however it wants to.  It has quite a few Pascal language niceties that Delphi doesn't.  Even Generics and Unicode support are other areas where FreePascal differs greatly from Delphi.  But, FreePascal does have special compatibility modes meant for migrating Delphi code to FreePascal.  In those modes, it tries to closely emulate Delphi 7 or 2009, depending on whether Unicode is being emulated or not.

Share this post


Link to post
On 4/1/2019 at 4:50 PM, PeterPanettone said:

Thanks, Stefan.

 

I would have preferred "the old way" which is more formal.

 

BTW, are there any drawbacks in using inline variables? I am not sure, but I remember having read somewhere that there is still a bug in using inline variables.

Sometimes, type inference can cause an internal error, e.g. when the type is TArray<something>. If you specify the type, it works.

Share this post


Link to post

This works well in our 10.3 production code, so it is not entirely useless.  The THardAllocList is a TList<T>, though - not a TArray<T>.

Several typeless inline declarations with initialization, and a inline string var with initalization.

procedure TPSDTask_ImportCustomerOrders.ProcessHardAllocations(const aDeliveryId: Integer;
  const HardAllocations: THardAllocList);
begin
  for var Alloc in HardAllocations
  do begin
    var TPack := GlobalTPackList.FindByTPackNo(Alloc.TPackNo, True, True);
    if Assigned(TPack)
    then begin
      var TPQ := TPack.GetQuantityOfArticleOnTPack(Alloc.ArticleId);
      var ArtSum := GlobalArticleSummaryList.FindByArticleId(Alloc.ArticleId);
      if ArtSum.QuantitiesAreEqual(Alloc.Quantity, TPQ)
      then begin
        if TPack.AllocatedDeliveryId = 0
        then begin // Allokér TPack til leveranse
          var AllocMsg: string := '';
          if TPack.AllocateToDelivery(aDeliveryId, AllocMsg, True) = rOK

Share this post


Link to post
6 hours ago, Lars Fosdal said:

 


procedure TPSDTask_ImportCustomerOrders.ProcessHardAllocations(const aDeliveryId: Integer;
  const HardAllocations: THardAllocList);
begin
  for var Alloc in HardAllocations
  do begin
    var TPack := GlobalTPackList.FindByTPackNo(Alloc.TPackNo, True, True);
    if Assigned(TPack)
    then begin
      var TPQ := TPack.GetQuantityOfArticleOnTPack(Alloc.ArticleId);
      var ArtSum := GlobalArticleSummaryList.FindByArticleId(Alloc.ArticleId);
      if ArtSum.QuantitiesAreEqual(Alloc.Quantity, TPQ)
      then begin
        if TPack.AllocatedDeliveryId = 0
        then begin // Allokér TPack til leveranse
          var AllocMsg: string := '';
          if TPack.AllocateToDelivery(aDeliveryId, AllocMsg, True) = rOK

 

 

I don't have 10.3 installed - so quick question on variables defined inline within a loop.   I assume they uninitialized with each iteration, correct?  (Or initialized exactly the same as normal stack variables) Technically then var AllocMsg :String := ''; in your example the null string default assignment is not needed?  Also the variables TPQ and ArtSum are assumedly interfaces which are automatically released on each iteration?

 

 

Share this post


Link to post

They would be uninitialized per iteration.

Ref. AllocMsg - what can I say other than old habits die hard 😛 
TPQ and ArtSum are regular objects retrieved from global shared pools and life cycle management happens elsewhere.

  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×