Static local variables available?

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Static local variables available?

Bo Berglund
I am trying to clean up an existing application where handling of
incoming serial data is done inside an event function OnRxData() of
the serial component.
I want to move the processing into a regular procedure so I can later
add a different hardware channel (TCP/IP) as a user choice.

Now when looking at the existing code in the RxData() procedure I see
that there is a while loop retrieving one character at a time from the
serial port and processing it. In the processing these characters are
stuffed into a temp string buffer until the complete packet is ready.

If I divide the single procedure into two where the event procedure
would have the while loop extracting the character and then call a
handling procedure with the char as argument then the processor cannot
have the while, but it must have the buffer...

The only way I could imagine this to work is if:
1) I use a globally defined string variable as buffer
2) It is somehow possible to define the buffer as a static local var.

So since I don't really want to use a global, is it possible to
declare a local variable static in the sense that it retains its
values across calls to the procedure?
If so how is it done?

--
Bo Berglund
Developer in Sweden

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Static local variables available?

Maciej Izak
2017-07-20 11:03 GMT+02:00 Bo Berglund <[hidden email]>:
So since I don't really want to use a global, is it possible to
declare a local variable static in the sense that it retains its
values across calls to the procedure?
If so how is it done?

procedure foo;
{$PUSH}
const{$J+}
  s : string ='';
{$POP}
begin
  writeln(s);
  if s = '' then
    s := 'hello from static local variable';
end;

begin
  foo; // will print empty line
  foo; // will print 'hello from static local variable'
  foo; // will print 'hello from static local variable'
end.

--
Best regards,
Maciej Izak

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Static local variables available?

Free Pascal - General mailing list
On 20.07.2017 11:11, Maciej Izak wrote:

> 2017-07-20 11:03 GMT+02:00 Bo Berglund <[hidden email]
> <mailto:[hidden email]>>:
>
>     So since I don't really want to use a global, is it possible to
>     declare a local variable static in the sense that it retains its
>     values across calls to the procedure?
>     If so how is it done?
>
>
> procedure foo;
> {$PUSH}
> const{$J+}
>   s : string ='';
> {$POP}
> begin
>   writeln(s);
>   if s = '' then
>     s := 'hello from static local variable';
> end;
>
> begin
>   foo; // will print empty line
>   foo; // will print 'hello from static local variable'
>   foo; // will print 'hello from static local variable'
> end.

For completeness sake:
https://www.freepascal.org/docs-html/current/ref/refse10.html#x22-210002.2
, especially the remark at the end.

Regards,
Sven

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Static local variables available?

Bo Berglund
In reply to this post by Maciej Izak
On Thu, 20 Jul 2017 11:11:50 +0200, Maciej Izak
<[hidden email]> wrote:

>2017-07-20 11:03 GMT+02:00 Bo Berglund <[hidden email]>:
>
>> So since I don't really want to use a global, is it possible to
>> declare a local variable static in the sense that it retains its
>> values across calls to the procedure?
>> If so how is it done?
>>
>
>procedure foo;
>{$PUSH}
>const{$J+}
>  s : string ='';
>{$POP}

Thanks,
but it looks a bit involved, probably better to use an object field
variable instead only accessible from the internal methods.


--
Bo Berglund
Developer in Sweden

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Static local variables available?

Free Pascal - General mailing list

Am 20.07.2017 13:01 schrieb "Bo Berglund" <[hidden email]>:
>
> On Thu, 20 Jul 2017 11:11:50 +0200, Maciej Izak
> <[hidden email]> wrote:
>
> >2017-07-20 11:03 GMT+02:00 Bo Berglund <[hidden email]>:
> >
> >> So since I don't really want to use a global, is it possible to
> >> declare a local variable static in the sense that it retains its
> >> values across calls to the procedure?
> >> If so how is it done?
> >>
> >
> >procedure foo;
> >{$PUSH}
> >const{$J+}
> >  s : string ='';
> >{$POP}
>
> Thanks,
> but it looks a bit involved, probably better to use an object field
> variable instead only accessible from the internal methods.

If you don't want to use $push/$pop then you can also simply enable $J+ for the whole unit. But this will also mean that global constants are writable.

Regards,
Sven


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Static local variables available?

Santiago A.
El 20/07/2017 a las 15:50, Sven Barth via fpc-pascal escribió:

Am 20.07.2017 13:01 schrieb "Bo Berglund" <[hidden email]>:
>
> On Thu, 20 Jul 2017 11:11:50 +0200, Maciej Izak
> <[hidden email]> wrote:
>
> >2017-07-20 11:03 GMT+02:00 Bo Berglund <[hidden email]>:
> >
> >> So since I don't really want to use a global, is it possible to
> >> declare a local variable static in the sense that it retains its
> >> values across calls to the procedure?
> >> If so how is it done?
> >>
> >
> >procedure foo;
> >{$PUSH}
> >const{$J+}
> >  s : string ='';
> >{$POP}
>
> Thanks,
> but it looks a bit involved, probably better to use an object field
> variable instead only accessible from the internal methods.

If you don't want to use $push/$pop then you can also simply enable $J+ for the whole unit. But this will also mean that global constants are writable.

Well, I'm an old dog so I prefer old fashion ways. A variable that retains its value is, from memory point of view, a global variable. I mean, the memory is never freed, it's not freed when it goes out of scope. So, the problem is what to do to limit the visibility to the procedure.

What about the old interface/implementation ways? You can't limit the visibility to the procedure, but you can limit the visibility to the implementation, so it is globally invisible.

unit hiddenVar;

interface

  procedure foo;
  procedure resetFoo;

implementation

var
 HiddenValue:integer;

procedure foo;
begin
 writeln(HiddenValue);
 inc(HiddenValue);
end;

procedure resetFoo;
begin
 HiddenValue:=0;
end;

initialization
  resetFoo;
end.

-- 
Saludos

Santiago A.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Static local variables available?

Free Pascal - General mailing list

Am 21.07.2017 10:44 schrieb "Santiago A." <[hidden email]>:
>
> El 20/07/2017 a las 15:50, Sven Barth via fpc-pascal escribió:
>>
>> Am 20.07.2017 13:01 schrieb "Bo Berglund" <[hidden email]>:
>> >
>> > On Thu, 20 Jul 2017 11:11:50 +0200, Maciej Izak
>> > <[hidden email]> wrote:
>> >
>> > >2017-07-20 11:03 GMT+02:00 Bo Berglund <[hidden email]>:
>> > >
>> > >> So since I don't really want to use a global, is it possible to
>> > >> declare a local variable static in the sense that it retains its
>> > >> values across calls to the procedure?
>> > >> If so how is it done?
>> > >>
>> > >
>> > >procedure foo;
>> > >{$PUSH}
>> > >const{$J+}
>> > >  s : string ='';
>> > >{$POP}
>> >
>> > Thanks,
>> > but it looks a bit involved, probably better to use an object field
>> > variable instead only accessible from the internal methods.
>>
>> If you don't want to use $push/$pop then you can also simply enable $J+ for the whole unit. But this will also mean that global constants are writable.
>
> Well, I'm an old dog so I prefer old fashion ways. A variable that retains its value is, from memory point of view, a global variable. I mean, the memory is never freed, it's not freed when it goes out of scope. So, the problem is what to do to limit the visibility to the procedure.

Writable constants *are* the old fashion way, cause this kind of usage stems from Turbo Pascal and allowed to restrict the visibility of symbols.

Regards,
Sven


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Static local variables available?

noreply
On 2017-07-21 07:16, Sven Barth via fpc-pascal wrote:

> Am 21.07.2017 10:44 schrieb "Santiago A." <[hidden email]>:
>>
>> El 20/07/2017 a las 15:50, Sven Barth via fpc-pascal escribió:
>>>
>>> Am 20.07.2017 13:01 schrieb "Bo Berglund" <[hidden email]>:
>>> >
>>> > On Thu, 20 Jul 2017 11:11:50 +0200, Maciej Izak
>>> > <[hidden email]> wrote:
>>> >
>>> > >2017-07-20 11:03 GMT+02:00 Bo Berglund <[hidden email]>:
>>> > >
>>> > >> So since I don't really want to use a global, is it possible
> to
>>> > >> declare a local variable static in the sense that it retains
> its
>>> > >> values across calls to the procedure?
>>> > >> If so how is it done?
>>> > >>
>>> > >
>>> > >procedure foo;
>>> > >{$PUSH}
>>> > >const{$J+}
>>> > >  s : string ='';
>>> > >{$POP}
>>> >
>>> > Thanks,
>>> > but it looks a bit involved, probably better to use an object
> field
>>> > variable instead only accessible from the internal methods.
>>>
>>> If you don't want to use $push/$pop then you can also simply enable
> $J+ for the whole unit. But this will also mean that global constants
> are writable.
>>
>> Well, I'm an old dog so I prefer old fashion ways. A variable that
> retains its value is, from memory point of view, a global variable. I
> mean, the memory is never freed, it's not freed when it goes out of
> scope. So, the problem is what to do to limit the visibility to the
> procedure.
>
> Writable constants *are* the old fashion way, cause this kind of usage
> stems from Turbo Pascal and allowed to restrict the visibility of
> symbols.
>
> Regards,
> Sven

Except really old fashioned might mean Modula

That's a neat idea to create a new module, and use it sort of like a
private object or static object just for the purpose of storing a global
variable in the private implementation section.

One disadvantage of modules (units) is that they add extra bytes to the
Exe, but is generally not an issue in desktop software. Previously when
people have asked for static C type things in fpc they were working with
embedded systems where every last byte counted and size of the program
was an issue. But, I don't know the use case in this episode..
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Loading...