Sign in Join

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

Mailing lists / fpc-pascal / 2003-01

typed constants

13 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

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

Mark Emerson

Michael Van Canneyt wrote:

[questions 1-3 and Michael's responses snipped]

Show quoted text 34 lines
> 4. If a typed constant is local to a procedure, then I assume it goes on > the stack, just as a local var would. Is this correct? No, it does not. > > 5. If 4 is yes...What value of a local typed constant gets pushed onto > the stack?....the original value specified in the const declaration? I > hope this is true, because then the compiler is guaranteeing to > initialize it in each new local context. Since it it not on the stack: no; The matter is subject to discussion: for all practical purposes, the 'typed constants' behave as initialized variables, but initialized meaning 'initialized at program startup', NOT 'initialized when coming into scope'. This is how Borland's Delphi compiler handles it, and so for compatibility reasons, Free Pascal implements it in the same way. A local 'typed constant' is no different from a global one, with the exception that it's name is only locally defined. Small note: Delphi (and Free Pascal) support 'initialized variables' This is simply the same as a 'global constant' which is not declared in the constant block, but in the variable block. Var S : Ansistring = Nil; For this to work in Free Pascal, Delphi compatibility mode must be invoked. But, and this is the reason I mention this: Delphi does NOT allow initialization of local variables.

It does not compile because of the "nil"...changing it to "abc" works.

Show quoted text 18 lines
> > I recommend clarifying the matter from questions 4 and 5 in the ref > manual, in your discussion of typed constants, as your discussion (on > page 19) refers to the initialization only "when the progam > starts"....whereas I would like to see the words "when the progam > starts (for a global typed constant) or when the procedure or function is > called (for a local typed constant)". It should be 'when the progam starts' in all cases. I'll bring it to the attention of the other compiler developers; It may be desirable to change this behaviour under certain circumstances. Thank you for pointing out the ambiguity; I will rewrite the part about the local typed constants in the manual, so it is clear what exactly can be expected. Michael.

One of the cardinal rules of programming is to initialize local variables...else the results can be unpredictable and hard to debug. The concept of having the compiler do this, via a construct such as a typed constant (or better yet, a var with an initialization value) is something I've wanted for years. I'm disappointed to hear that this is NOT the case with FPC, and that these constructs initialize only at the global (i.e. program start) level.

What, pray tell, does that imply for a LOCAL typed constant? Where is the devilish thing stored, if not on the stack? Does it get stored globally? If so, that means that different (or recursive) invocations of the procedure will be operating on this variable in a counter-intuitive way. If this is so, I see no reason to ever place one of them in any local declaration [unless I wish to confuse myself :) ].

I recommend to the compiler guys (when schedule permits) implementing the compiler initilization of local variables (which have an initialization value declared)...that is, it gets initialized when it gets pushed onto the stack.

In the meantime, I suggest that the documentation be clarified with respect to what is and what is not happening in this matter.

Happy New Year!

Mark

Unknown author
to Mark Emerson
Mark Emerson wrote 25 lines
> > I recommend clarifying the matter from questions 4 and 5 in the ref > > manual, in your discussion of typed constants, as your discussion (on > > page 19) refers to the initialization only "when the progam > > starts"....whereas I would like to see the words "when the progam > > starts (for a global typed constant) or when the procedure or function is > > called (for a local typed constant)". > > It should be 'when the progam starts' in all cases. > > I'll bring it to the attention of the other compiler developers; > It may be desirable to change this behaviour under certain circumstances. > > Thank you for pointing out the ambiguity; I will rewrite the part about > the local typed constants in the manual, so it is clear what exactly can > be expected. > > Michael. One of the cardinal rules of programming is to initialize local variables...else the results can be unpredictable and hard to debug. The concept of having the compiler do this, via a construct such as a typed constant (or better yet, a var with an initialization value) is something I've wanted for years. I'm disappointed to hear that this is NOT the case with FPC, and that these constructs initialize only at the global (i.e. program start) level.

It is also like this in Delphi, this has been tested.

Show quoted text 7 lines
What, pray tell, does that imply for a LOCAL typed constant? Where is the devilish thing stored, if not on the stack? Does it get stored globally? If so, that means that different (or recursive) invocations of the procedure will be operating on this variable in a counter-intuitive way. If this is so, I see no reason to ever place one of them in any local declaration [unless I wish to confuse myself :) ].

The local typed constant is stored globally.
Although I agree with your reasoning, there is a reason to use them anyway: Naming scope rules allow you to define a 'temporary' local type.

Show quoted text 5 lines
I recommend to the compiler guys (when schedule permits) implementing the compiler initilization of local variables (which have an initialization value declared)...that is, it gets initialized when it gets pushed onto the stack.

The matter is being discussed by the core members. The response I've had till now indicate that probably we'll implement it as initialized variables.

So the following will be allowed

program recurs;
Procedure doit (N : Integer);
Const
  C : Integer = 1;
Var
  A : Integer = 0;
begin
  Writeln('Old value : ',A);
  A:=A+N;
  Writeln('New Value : ',A);
  If N<10 then
    Doit(N+1);
end;
begin
  Doit(1);
end.
-------------------------------------------------

Both the variable A and typed constant C will be initialized at procedure entry.

Note that Delphi *explicitly* does not allow this. Whether we should retain the Delphi behaviour in Delphi mode is still a discussion point.

In the meantime, I suggest that the documentation be clarified with respect to what is and what is not happening in this matter.

It will be done, as stated earlier.

Michael.

Unknown author
to Unknown author

Hi,

This is a follow-up on the 'typed local const' issue:

Peter Vreman implemented support for initialized local variables in the 1.1 version of the compiler.

This means that:

1. Local typed constants retain their current behaviour (Compatible with Delphi and TP):

Local typed constants are initialized at program startup. If they are modified during the execution of the procedure in which they are defined, they will retain this modified value across calls to this procedure.

This is true in both 1.1 and 1.0 version of the compiler.

Consider the following program :

   program tinivar;
   procedure p1;
   Const
     a : integer = 1;
   begin
     writeln(a);
     if a1 then
       halt(1);
     inc(a);
   end;
   begin
     p1;
     p1;
   end.
   This will print
   1
   2
   and exits with code 1
   This is compatible with Delphi/TP.

2. Initialized local variables will be initialized on procedure entry when compiled using version 1.1 of the compiler.
Programs compiled with version 1.0 of the compiler retain their current behaviour, as in the case of a 'local typed constant'.

Consider the following program:

   program tinivar;
   procedure p1;
   Var
     a : integer = 1;
   begin
     writeln(a);
     if a1 then
       halt(1);
     inc(a);
   end;
   begin
     p1;
     p1;
   end.
   Compiled with version 1.1, this will print
   1
   1
   and exits with code 0
   Compiled with version 1.0, this will do the same as if 'a' was
   a local typed constant.
   Note that this behaviour is does not conflict with Delphi,
   since neither TP nor Delphi allow this.

There are no plans to back-port this to version 1.0 of the compiler, because the compiler internals are too different for this to be feasible in a reasonable period.

People that want initialized variables will have to switch to the 1.1 compiler, snapshots with this new behaviour should become availabe soon. The patch for this is already in CVS.

Michael.

Vinzent Hoefler
to Unknown author: It is also like this in Delphi, this has been tested. The local typed constant is stored…
Show quoted text 11 lines
So the following will be allowed program recurs; Procedure doit (N : Integer); Const C : Integer = 1; Var A : Integer = 0;

Is this a typo? This should be

|A : Integer := 0;

shouldn't it? I mean it is a variable, so you can only *assign* an initial value to it instead of setting it equal to some value.

Ok, one could argue, the (local) typed constant thing *is* a variable, too, but at least we *call* it constant, even if in real world it is not. IMO it would be more consistent to not allow a variable to be set with the "=" operator. Consider this:

|Var
|  A : boolean = C = D;

Looks a little bit crazy to me.

Vinzent.

God is a polytheist.
Peter Vreman
to Vinzent Hoefler
Show quoted text 20 lines
On Thursday 02 January 2003 04:28, wrote: > So the following will be allowed > > program recurs; > > Procedure doit (N : Integer); > > Const > C : Integer = 1; > > Var > A : Integer = 0; Is this a typo? This should be |A : Integer := 0; shouldn't it? I mean it is a variable, so you can only *assign* an initial value to it instead of setting it equal to some value.
Go and tell Borland about it, they use '=' for assigning enums. FPC
already supported that with ':='.

It's all about compatibility. When we are not compatible with Delphi we get a lot of bug reports.

Show quoted text 9 lines
Ok, one could argue, the (local) typed constant thing *is* a variable, too, but at least we *call* it constant, even if in real world it is not. IMO it would be more consistent to not allow a variable to be set with the "=" operator. Consider this: |Var | A : boolean = C = D; Looks a little bit crazy to me.

That is also not allowed. You need to specify a constant value.

Vinzent Hoefler
to Peter Vreman
Peter Vreman wrote 19 lines
> On Thursday 02 January 2003 04:28, wrote: >> Procedure doit (N : Integer); >> >> Const >> C : Integer = 1; >> >> Var >> A : Integer = 0; > > Is this a typo? This should be > > |A : Integer := 0; > > shouldn't it? I mean it is a variable, so you can only *assign* an > initial value to it instead of setting it equal to some value. Go and tell Borland about it, they use '=' for assigning enums. FPC already supported that with ':='.

*eeek* In Delphi you can write the following?

|var
|  X : some_enum = enum_value;

I thought, this kind of syntax is only allowed for typed "constants"?

<cite>
|> I recommend to the compiler guys (when schedule permits) implementing |> the compiler initilization of local variables (which have an |> initialization value declared)...that is, it gets initialized when it |> gets pushed onto the stack.
|
|The matter is being discussed by the core members. |The response I've had till now indicate that probably we'll implement |it as initialized variables.
</cite>

So I did not understand the last sentence correctly?

It's all about compatibility. When we are not compatible with Delphi we get a lot of bug reports.

Even if it is right..., yes I know. So "initialized variables" are already supported in Delphi and you simply have to be compatible?

Show quoted text 7 lines
> with the "=" operator. Consider this: > |Var > | A : boolean = C = D; > > Looks a little bit crazy to me. That is also not allowed. You need to specify a constant value.

Well, at least with

|const
|  C = 5;
|  D = 6;

the line above should legally evaluate to False as initial value for A. However, I even see no reason why

|procedure Do_It (C, D : Integer);
|var
|  A : boolean := C = D;

shouldn't be allowed for initialization.

Vinzent.

Mathematicians do it in theory.
Unknown author
to Vinzent Hoefler
Vinzent Hoefler wrote 27 lines
On Thursday 02 January 2003 08:43, Peter Vreman wrote: > > On Thursday 02 January 2003 04:28, wrote: > > >> Procedure doit (N : Integer); > >> > >> Const > >> C : Integer = 1; > >> > >> Var > >> A : Integer = 0; > > > > Is this a typo? This should be > > > > |A : Integer := 0; > > > > shouldn't it? I mean it is a variable, so you can only *assign* an > > initial value to it instead of setting it equal to some value. > > Go and tell Borland about it, they use '=' for assigning enums. FPC > already supported that with ':='. *eeek* In Delphi you can write the following? |var | X : some_enum = enum_value; I thought, this kind of syntax is only allowed for typed "constants"?

No:

Type
  TEnum = (enOne,entwo,enThree=4);

In Free pascal, it was:

Type
  TEnum = (enOne,entwo,enThree:=4);

Its main purpose is to support translation of C enums

Show quoted text 42 lines
<cite> |> I recommend to the compiler guys (when schedule permits) implementing |> the compiler initilization of local variables (which have an |> initialization value declared)...that is, it gets initialized when it |> gets pushed onto the stack. | |The matter is being discussed by the core members. |The response I've had till now indicate that probably we'll implement |it as initialized variables. </cite> So I did not understand the last sentence correctly? > It's all about compatibility. When we are not compatible with Delphi > we get a lot of bug reports. Even if it is right..., yes I know. So "initialized variables" are already supported in Delphi and you simply have to be compatible? > > with the "=" operator. Consider this: > > |Var > > | A : boolean = C = D; > > > > Looks a little bit crazy to me. > > That is also not allowed. You need to specify a constant value. Well, at least with |const | C = 5; | D = 6; the line above should legally evaluate to False as initial value for A. However, I even see no reason why |procedure Do_It (C, D : Integer); |var | A : boolean := C = D; shouldn't be allowed for initialization.
Peter was wrong, it is allowed (note the use of '=', not ':='):
program  tini;
Const
  A = 1;
  B = 2;
Procedure ProcA;
Var
  C : Integer = A+B;
  D : Boolean = (A=B);
begin
  Writeln(c);
  Writeln(d);
end;
begin
  Proca;
end.

With correct output :
home: >ppc386-1.1 tini.pp
home: >tini
3
FALSE

Michael.

Unknown author
to Unknown author

On Thu, 2 Jan 2003 wrote:

Correction:

Show quoted text 8 lines
> > |procedure Do_It (C, D : Integer); > |var > | A : boolean := C = D; > > shouldn't be allowed for initialization. Peter was wrong, it is allowed (note the use of '=', not ':='):

I was mistaken here, I failed to note that C and D are function arguments, while I assumed in my answer that they were constants defined elsewhere.

Thus Peter's original statement is of course correct: this is not supported.

My apologies for any confusion this may have caused.

Michael.

Aitor Santamaría Merino
to Unknown author: No: Type TEnum = (enOne,entwo,enThree=4); In Free pascal, it was: Type TEnum =…
Show quoted text 10 lines
Type TEnum = (enOne,entwo,enThree=4); In Free pascal, it was: Type TEnum = (enOne,entwo,enThree:=4); Its main purpose is to support translation of C enums

Just a sidenote curiosity, talking about supported and not supported, I noticed (by chance ;-)) that FPC also allows the use of C's operators << and >> (which I prefer over SHR and SHL), but makes me wonder of the convenience of having these operators regarding compatibility. Probably it was said or written in some documentation, or I am completely mislead and this is a Delphi feature (or perhaps there's a switch to compile in pure BorlandPascal).

Aitor

Vinzent Hoefler
to Unknown author: No: Type TEnum = (enOne,entwo,enThree=4); In Free pascal, it was: Type TEnum =…
Show quoted text 18 lines
On Thu, 2 Jan 2003, Vinzent Hoefler wrote: > On Thursday 02 January 2003 08:43, Peter Vreman wrote: > > Go and tell Borland about it, they use '=' for assigning enums. > > FPC already supported that with ':='. > > *eeek* In Delphi you can write the following? > > |var > | X : some_enum = enum_value; > > I thought, this kind of syntax is only allowed for typed > "constants"? No: Type TEnum = (enOne,entwo,enThree=4);

Oh, this one. To assign specific values to an enum position. Well, this can be considered as a constant value, so the "=" would be quite ok for me.

Show quoted text 6 lines
In Free pascal, it was: Type TEnum = (enOne,entwo,enThree:=4); Its main purpose is to support translation of C enums

The intention is clear (in C, enums are just named integer constants anyway).

[I just wouldn't like to have declaration and implementation at the same place. The Ada approach with its representation clauses looks more appealing to me.]

Show quoted text 7 lines
> > > with the "=" operator. Consider this: > > > |Var > > > | A : boolean = C = D; > > > > > > Looks a little bit crazy to me. > > > > That is also not allowed. You need to specify a constant value.

[I think this one is clarified now, thanks]

Show quoted text 11 lines
program tini; Const A = 1; B = 2; Procedure ProcA; Var C : Integer = A+B; D : Boolean = (A=B);

To get back to the point, I understood that this will "probably be implemented as initialized variables."
[see ]

Rereading that message again seems to reveal to me, that this means _both_ syntactic forms will be implemented as initalized variables? *dizzled*

I thought, the only difference between local typed constants and initialized variables will be that

(a) the "const" declaration implements them as global with just local scope and

(b) "var" would initialize it each time the subprogram is called?

And especially in case of (b), why should it not be allowed to use variable parameters as initialization value?

Anyway, I would think that an assignment operator ":=" is more appropriate for a variable assignment in those cases. It would also help to distinguish between both cases then, because people tend to write declarations in single const/var blocks, so you cannot tell from the first look, if this one is a local typed constant or an initialized variable. With the distinction between "=" and ":=" you could do that.

Show quoted text 5 lines
With correct output : home: >ppc386-1.1 tini.pp home: >tini 3 FALSE

I did not expect otherwise. :-)

Vinzent.

There are three kinds of lies: Lies, Damn Lies, and Statistics. -- Disraeli
Peter Vreman
to Vinzent Hoefler
Show quoted text 10 lines
I thought, the only difference between local typed constants and initialized variables will be that (a) the "const" declaration implements them as global with just local scope and (b) "var" would initialize it each time the subprogram is called? And especially in case of (b), why should it not be allowed to use variable parameters as initialization value?

Simpel answer: the current code was already available for the reading of typed constants. Only the implicit generation of the assignments was needed. It took only 30 minutes to get it working.

Show quoted text 6 lines
Anyway, I would think that an assignment operator ":=" is more appropriate for a variable assignment in those cases. It would also help to distinguish between both cases then, because people tend to write declarations in single const/var blocks, so you cannot tell from the first look, if this one is a local typed constant or an initialized variable. With the distinction between "=" and ":=" you could do that.

I don't see the problem there is currently a clear distinction. In statements you need to use := for assignment. And in declarations (enums,default parameters, typed constants, initialized vars) you need to use =.

Vinzent Hoefler
to Peter Vreman

On Thursday 02 January 2003 14:08, Peter Vreman wrote:

[initialized variabels vs. typed constants]

Show quoted text 6 lines
> And especially in case of (b), why should it not be allowed to use > variable parameters as initialization value? Simpel answer: the current code was already available for the reading of typed constants. Only the implicit generation of the assignments was needed. It took only 30 minutes to get it working.

That's the whole reason? Simple code reuse? Ok, that's a good one. ;-)

I don't see the problem there is currently a clear distinction. In statements you need to use := for assignment. And in declarations (enums,default parameters, typed constants, initialized vars) you need to use =.

Ok, if you see it that way, it looks rather ok.

OTOH, the initialization of variables would be just a shortcut for doing it myself at the beginning of the procedure ..., so it is more like an assignment than a declaration!?

Vinzent.

Human beings were created by water to transport it uphill.