Sign in Join

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

Mailing lists / fpc-pascal / 2020-11

Initialization of constant record member of pointer type

17 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

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

LacaK

Hi,

is there a way how to initialize record member of pointer type (other than PChar) in the following example:

type
   TMyRec=record
     a: PByte; // if I change PByte to PAnsiChar then it works
   end;
const
   MyConst: TMyRec = (a: 'abcd'); // I want to a points to static memory
where 'abcd' is stored

I would like to initialize a to be pointer to another known constant or directly to supplied string constant.

For example something like:

const
   MyConst1='abcd';
   MyConst2=TMyRec = (a: @MyConst1);

TIA

-Laco.

Reply by email

Sven Barth
to LacaK
LacaK wrote 22 lines
Hi, is there a way how to initialize record member of pointer type (other than PChar) in the following example: type   TMyRec=record     a: PByte; // if I change PByte to PAnsiChar then it works   end; const   MyConst: TMyRec = (a: 'abcd'); // I want to a points to static memory where 'abcd' is stored I would like to initialize a to be pointer to another known constant or directly to supplied string constant. For example something like: const   MyConst1='abcd';   MyConst2=TMyRec = (a: @MyConst1);

Untyped constants don't have an address you can take. You need to use a typed constant:

=== code begin ===

const
   MyConst1: Byte = 123;
   MyConst2: TMyRec = (a: @MyConst1);

=== code end ===

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 32 lines
Am 30.11.2020 um 13:20 schrieb LacaK via fpc-pascal: > Hi, > > is there a way how to initialize record member of pointer type (other > than PChar) in the following example: > > type >   TMyRec=record >     a: PByte; // if I change PByte to PAnsiChar then it works >   end; > > const >   MyConst: TMyRec = (a: 'abcd'); // I want to a points to static > memory where 'abcd' is stored > > I would like to initialize a to be pointer to another known constant > or directly to supplied string constant. > > For example something like: > > const >   MyConst1='abcd'; >   MyConst2=TMyRec = (a: @MyConst1); Untyped constants don't have an address you can take. You need to use a typed constant: === code begin === const   MyConst1: Byte = 123;   MyConst2: TMyRec = (a: @MyConst1);

Does this also work with variables ?

Might be worth writing in the documentation...

Michael.

Reply by email

LacaK
to Sven Barth: Untyped constants don't have an address you can take. You need to use a typed constant:…

Dňa 30.11.2020 o 23:26 Sven Barth via fpc-pascal napísal(a):

Show quoted text 35 lines
Am 30.11.2020 um 13:20 schrieb LacaK via fpc-pascal: > Hi, > > is there a way how to initialize record member of pointer type (other > than PChar) in the following example: > > type >   TMyRec=record >     a: PByte; // if I change PByte to PAnsiChar then it works >   end; > > const >   MyConst: TMyRec = (a: 'abcd'); // I want to a points to static > memory where 'abcd' is stored > > I would like to initialize a to be pointer to another known constant > or directly to supplied string constant. > > For example something like: > > const >   MyConst1='abcd'; >   MyConst2=TMyRec = (a: @MyConst1); Untyped constants don't have an address you can take. You need to use a typed constant: === code begin === const   MyConst1: Byte = 123;   MyConst2: TMyRec = (a: @MyConst1); === code end ===

Thank you, yes it works. I have used:

const
   MyConst1: AnsiString = 'abc'
   MyConst2: TMyRec = (a: @MyConst1[1]);

unfortunately it seems, that I can not use Length(MyConst1) in:

type
   TMyRec=record
     l: integer;
     a: PByte;
   end;
const
   MyConst1: AnsiString = 'abc';
   MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]);

Why is it prohibited?

-Laco.

Reply by email

Sven Barth
to LacaK

LacaK via fpc-pascal schrieb am Di., 1.
Dez. 2020, 11:00:

Show quoted text 57 lines
Dňa 30.11.2020 o 23:26 Sven Barth via fpc-pascal napísal(a): > Am 30.11.2020 um 13:20 schrieb LacaK via fpc-pascal: >> Hi, >> >> is there a way how to initialize record member of pointer type (other >> than PChar) in the following example: >> >> type >> TMyRec=record >> a: PByte; // if I change PByte to PAnsiChar then it works >> end; >> >> const >> MyConst: TMyRec = (a: 'abcd'); // I want to a points to static >> memory where 'abcd' is stored >> >> I would like to initialize a to be pointer to another known constant >> or directly to supplied string constant. >> >> For example something like: >> >> const >> MyConst1='abcd'; >> MyConst2=TMyRec = (a: @MyConst1); > > Untyped constants don't have an address you can take. You need to use > a typed constant: > > === code begin === > > const > MyConst1: Byte = 123; > MyConst2: TMyRec = (a: @MyConst1); > > === code end === > Thank you, yes it works. I have used: const MyConst1: AnsiString = 'abc' MyConst2: TMyRec = (a: @MyConst1[1]); unfortunately it seems, that I can not use Length(MyConst1) in: type TMyRec=record l: integer; a: PByte; end; const MyConst1: AnsiString = 'abc'; MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]); Why is it prohibited?

Because MyConst1 is not an *untyped* constant. Only untyped constants can be used in constant expressions (a pointer to something can be considered an untyped constant).

The following might work though I did not test it:

=== code begin ===

const
   MyStr = 'abc'
   MyConst1: AnsiString = MyStr;
   MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]);

=== code end ===

Regards,
Sven

Reply by email

Ladislav Karrach
to Sven Barth
Show quoted text 17 lines
Because MyConst1 is not an *untyped* constant. Only untyped constants can be used in constant expressions (a pointer to something can be considered an untyped constant). The following might work though I did not test it: === code begin === const    MyStr = 'abc'    MyConst1: AnsiString = MyStr;    MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]); === code end ===

Yes it works, but I must define 2 constants (MyStr and MyConst1), which is not so nice ;-)

It would be nice to have support for true constants:

const
    MyConst1 = 'abc' ;
    MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]);

But may be that there are technical reasons why it is problematic (may be that true constants are stored in another memory locations, which can not be easy addressed)

Thanks

-Laco.

Reply by email

Michael Van Canneyt
to Ladislav Karrach
Ladislav Karrach wrote 32 lines
> > Because MyConst1 is not an *untyped* constant. Only untyped constants > can be used in constant expressions (a pointer to something can be > considered an untyped constant). > > The following might work though I did not test it: > > === code begin === > > const >    MyStr = 'abc' >    MyConst1: AnsiString = MyStr; >    MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]); > > > === code end === > Yes it works, but I must define 2 constants (MyStr and MyConst1), which is not so nice ;-) It would be nice to have support for true constants: const    MyConst1 = 'abc' ;    MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]); But may be that there are technical reasons why it is problematic (may be that true constants are stored in another memory locations, which can not be easy addressed) From a pure language point of view, true constants do not "exist".

They are substituted wherever the compiler finds a reference. So there is no address in memory.

A typed constant is like a variable (it is the precursor of the initialized variable), it has an address in memory.

Michael.

Reply by email

Tomas Hajny
to Ladislav Karrach: Yes it works, but I must define 2 constants (MyStr and MyConst1), which is not so nice ;-)
Ladislav Karrach wrote 29 lines
> > Because MyConst1 is not an *untyped* constant. Only untyped constants > can be used in constant expressions (a pointer to something can be > considered an untyped constant). > > The following might work though I did not test it: > > === code begin === > > const >    MyStr = 'abc' >    MyConst1: AnsiString = MyStr; >    MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]); > > > === code end === > Yes it works, but I must define 2 constants (MyStr and MyConst1), which is not so nice ;-) It would be nice to have support for true constants: const    MyConst1 = 'abc' ;    MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]); But may be that there are technical reasons why it is problematic (may be that true constants are stored in another memory locations, which can not be easy addressed)

Yes, that's one of possible reasons.

Regarding Length in constant value assignment - remember that Length is a function. In case of real constants, the call may be replaced by the compiler with the constant value. However typed constants may not be constant, so generic replacement throughout the source code at compile time is not possible (if it appears in the main body or some function, the length may already be changed to something else) and selective replacement may result in a behaviour not expected by the user. The only questionable case is IMHO the case of {$WRITEABLECONST OFF} - the compiler _might_ be able to perform the compile-time substition in that case (and thus allow using Length of such a constant in constant value assignment), but it doesn't do that in that case either apparently.

Tomas

Reply by email

LacaK
to Tomas Hajny

Dňa 2.12.2020 o 13:55 Tomas Hajny via fpc-pascal napísal(a):

Show quoted text 45 lines
On 2020-12-01 11:39, Ladislav Karrach via fpc-pascal wrote: >> >> Because MyConst1 is not an *untyped* constant. Only untyped >> constants can be used in constant expressions (a pointer to >> something can be considered an untyped constant). >> >> The following might work though I did not test it: >> >> === code begin === >> >> const >>    MyStr = 'abc' >>    MyConst1: AnsiString = MyStr; >>    MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]); >> >> >> === code end === >> > Yes it works, but I must define 2 constants (MyStr and MyConst1), > which is not so nice ;-) > > It would be nice to have support for true constants: > > const >    MyConst1 = 'abc' ; >    MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]); > > But may be that there are technical reasons why it is problematic (may > be that true constants are stored in another memory locations, which > can not be easy addressed) Yes, that's one of possible reasons. Regarding Length in constant value assignment - remember that Length is a function. In case of real constants, the call may be replaced by the compiler with the constant value. However typed constants may not be constant, so generic replacement throughout the source code at compile time is not possible (if it appears in the main body or some function, the length may already be changed to something else) and selective replacement may result in a behaviour not expected by the user. The only questionable case is IMHO the case of {$WRITEABLECONST OFF} - the compiler _might_ be able to perform the compile-time substition in that case (and thus allow using Length of such a constant in constant value assignment), but it doesn't do that in that case either apparently.

Yes I have no problem with {$WRITEABLECONST OFF} if it will allow Length().

Somewhere I read (may be in Delphi documentation) that some intristic functions like Low(), High(), Pred() and also Length() etc. can be used in constant expressions because compiler can evaluate them if theirs arguments are also constants.
Which is the case in my example.
For now {$WRITEABLECONST OFF} does not help ;-)

-Laco.

Reply by email

Tomas Hajny
to LacaK
LacaK wrote 57 lines
Dňa 2.12.2020 o 13:55 Tomas Hajny via fpc-pascal napísal(a): > On 2020-12-01 11:39, Ladislav Karrach via fpc-pascal wrote: >>> >>> Because MyConst1 is not an *untyped* constant. Only untyped >>> constants can be used in constant expressions (a pointer to >>> something can be considered an untyped constant). >>> >>> The following might work though I did not test it: >>> >>> === code begin === >>> >>> const >>>    MyStr = 'abc' >>>    MyConst1: AnsiString = MyStr; >>>    MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]); >>> >>> >>> === code end === >>> >> Yes it works, but I must define 2 constants (MyStr and MyConst1), >> which is not so nice ;-) >> >> It would be nice to have support for true constants: >> >> const >>    MyConst1 = 'abc' ; >>    MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]); >> >> But may be that there are technical reasons why it is problematic >> (may >> be that true constants are stored in another memory locations, which >> can not be easy addressed) > > Yes, that's one of possible reasons. > > Regarding Length in constant value assignment - remember that Length > is a function. In case of real constants, the call may be replaced by > the compiler with the constant value. However typed constants may not > be constant, so generic replacement throughout the source code at > compile time is not possible (if it appears in the main body or some > function, the length may already be changed to something else) and > selective replacement may result in a behaviour not expected by the > user. The only questionable case is IMHO the case of {$WRITEABLECONST > OFF} - the compiler _might_ be able to perform the compile-time > substition in that case (and thus allow using Length of such a > constant in constant value assignment), but it doesn't do that in that > case either apparently. Yes I have no problem with {$WRITEABLECONST OFF} if it will allow Length(). Somewhere I read (may be in Delphi documentation) that some intristic functions like Low(), High(), Pred() and also Length() etc. can be used in constant expressions because compiler can evaluate them if theirs arguments are also constants. Which is the case in my example. For now {$WRITEABLECONST OFF} does not help ;-)

Yes, that's what I mentioned as well, but it might be changed for this particular case. You might create a ticket for that if Delphi allows to use Length that way; obviously, you might create such a ticket even if Delphi doesn't allow to do that. ;-)

Tomas

Reply by email

LacaK
to Tomas Hajny

Dňa 2.12.2020 o 16:09 Tomas Hajny via fpc-pascal napísal(a):

Show quoted text 63 lines
On 2020-12-02 16:01, LacaK via fpc-pascal wrote: > Dňa 2.12.2020 o 13:55 Tomas Hajny via fpc-pascal napísal(a): >> On 2020-12-01 11:39, Ladislav Karrach via fpc-pascal wrote: >>>> >>>> Because MyConst1 is not an *untyped* constant. Only untyped >>>> constants can be used in constant expressions (a pointer to >>>> something can be considered an untyped constant). >>>> >>>> The following might work though I did not test it: >>>> >>>> === code begin === >>>> >>>> const >>>>    MyStr = 'abc' >>>>    MyConst1: AnsiString = MyStr; >>>>    MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]); >>>> >>>> >>>> === code end === >>>> >>> Yes it works, but I must define 2 constants (MyStr and MyConst1), >>> which is not so nice ;-) >>> >>> It would be nice to have support for true constants: >>> >>> const >>>    MyConst1 = 'abc' ; >>>    MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]); >>> >>> But may be that there are technical reasons why it is problematic (may >>> be that true constants are stored in another memory locations, which >>> can not be easy addressed) >> >> Yes, that's one of possible reasons. >> >> Regarding Length in constant value assignment - remember that Length >> is a function. In case of real constants, the call may be replaced >> by the compiler with the constant value. However typed constants may >> not be constant, so generic replacement throughout the source code >> at compile time is not possible (if it appears in the main body or >> some function, the length may already be changed to something else) >> and selective replacement may result in a behaviour not expected by >> the user. The only questionable case is IMHO the case of >> {$WRITEABLECONST OFF} - the compiler _might_ be able to perform the >> compile-time substition in that case (and thus allow using Length of >> such a constant in constant value assignment), but it doesn't do >> that in that case either apparently. > > Yes I have no problem with {$WRITEABLECONST OFF} if it will allow > Length(). > > Somewhere I read (may be in Delphi documentation) that some intristic > functions like Low(), High(), Pred() and also Length() etc. can be > used in constant expressions because compiler can evaluate them if > theirs arguments are also constants. > Which is the case in my example. > For now {$WRITEABLECONST OFF} does not help ;-) Yes, that's what I mentioned as well, but it might be changed for this particular case. You might create a ticket for that if Delphi allows to use Length that way; obviously, you might create such a ticket even if Delphi doesn't allow to do that. ;-)

I checked it with older Delphi XE and it seems, that Delphi XE does not support Length() for typed constant also when {$WRITEABLECONST OFF}

I do not believe that this will be accepted for FPC, so I don not open new feature request in bug tracker.

On other side FPC developers read this mailing list so if they consider this as a useful/doable feature may be that someone will take look at it ...

Thanks

-Laco.

Reply by email

Marc Weustink
to LacaK
LacaK wrote 73 lines
Dňa 2.12.2020 o 16:09 Tomas Hajny via fpc-pascal napísal(a): > On 2020-12-02 16:01, LacaK via fpc-pascal wrote: >> Dňa 2.12.2020 o 13:55 Tomas Hajny via fpc-pascal napísal(a): >>> On 2020-12-01 11:39, Ladislav Karrach via fpc-pascal wrote: >>>>> >>>>> Because MyConst1 is not an *untyped* constant. Only untyped >>>>> constants can be used in constant expressions (a pointer to >>>>> something can be considered an untyped constant). >>>>> >>>>> The following might work though I did not test it: >>>>> >>>>> === code begin === >>>>> >>>>> const >>>>>    MyStr = 'abc' >>>>>    MyConst1: AnsiString = MyStr; >>>>>    MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]); >>>>> >>>>> >>>>> === code end === >>>>> >>>> Yes it works, but I must define 2 constants (MyStr and MyConst1), >>>> which is not so nice ;-) >>>> >>>> It would be nice to have support for true constants: >>>> >>>> const >>>>    MyConst1 = 'abc' ; >>>>    MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]); >>>> >>>> But may be that there are technical reasons why it is problematic (may >>>> be that true constants are stored in another memory locations, which >>>> can not be easy addressed) >>> >>> Yes, that's one of possible reasons. >>> >>> Regarding Length in constant value assignment - remember that Length >>> is a function. In case of real constants, the call may be replaced >>> by the compiler with the constant value. However typed constants may >>> not be constant, so generic replacement throughout the source code >>> at compile time is not possible (if it appears in the main body or >>> some function, the length may already be changed to something else) >>> and selective replacement may result in a behaviour not expected by >>> the user. The only questionable case is IMHO the case of >>> {$WRITEABLECONST OFF} - the compiler _might_ be able to perform the >>> compile-time substition in that case (and thus allow using Length of >>> such a constant in constant value assignment), but it doesn't do >>> that in that case either apparently. >> >> Yes I have no problem with {$WRITEABLECONST OFF} if it will allow >> Length(). >> >> Somewhere I read (may be in Delphi documentation) that some intristic >> functions like Low(), High(), Pred() and also Length() etc. can be >> used in constant expressions because compiler can evaluate them if >> theirs arguments are also constants. >> Which is the case in my example. >> For now {$WRITEABLECONST OFF} does not help ;-) > > Yes, that's what I mentioned as well, but it might be changed for this > particular case. You might create a ticket for that if Delphi allows > to use Length that way; obviously, you might create such a ticket even > if Delphi doesn't allow to do that. ;-) > I checked it with older Delphi XE and it seems, that Delphi XE does not support Length() for typed constant also when {$WRITEABLECONST OFF} I do not believe that this will be accepted for FPC, so I don not open new feature request in bug tracker. On other side FPC developers read this mailing list so if they consider this as a useful/doable feature may be that someone will take look at it

I just happened to write a construct like this (in Delphi):

const
   X_0: array[0..4276] of SmallInt = (.....
   MAP: array['0'..'9'] of TSomething = (
     (Samples: @X_0; Count: Length(X_0)), ...

Marc

Reply by email

Luca Olivetti
to LacaK: Dňa 30.11.2020 o 23:26 Sven Barth via fpc-pascal napísal(a): Thank you, yes it works. I…

El 1/12/20 a les 11:00, LacaK via fpc-pascal ha escrit:

Show quoted text 5 lines
Thank you, yes it works. I have used: const   MyConst1: AnsiString = 'abc'   MyConst2: TMyRec = (a: @MyConst1[1]);

It doesn't compile with fpc 3.2.0 (I'm trying, without success so far, your open62541 translation).

In order to compile your TestOpcUa1 I had to change the definition to

   MyStructTypeName1 = 'MyStructTypeName';            // untyped
constant for for Length()
   MyStructTypeName2: Array[1..length(MyStructTypeName1)] of char =
MyStructTypeName1; // typed constant for @

and then use @MyStructTypeName1 (without the [1]) in the record definition. Note that without the [1] it would also compile with an ansistring, but then the pointer wouldn't point at the first character of the string.

Bye

Luca

Reply by email

LacaK
to Luca Olivetti
Show quoted text 9 lines
> Thank you, yes it works. I have used: > > const >    MyConst1: AnsiString = 'abc' >    MyConst2: TMyRec = (a: @MyConst1[1]); It doesn't compile with fpc 3.2.0 (I'm trying, without success so far, your open62541 translation).

Yes, you are right. That ^ compiles under FPC 3.0 but not under FPC 3.2

I have updated test program (now compiles also under FPC 3.2)

Thanks

-Laco.

Reply by email

LacaK
to Marc Weustink: I just happened to write a construct like this (in Delphi): const X_0: array[0..4276] of…
Show quoted text 80 lines
>>>>>> >>>>>> Because MyConst1 is not an *untyped* constant. Only untyped >>>>>> constants can be used in constant expressions (a pointer to >>>>>> something can be considered an untyped constant). >>>>>> >>>>>> The following might work though I did not test it: >>>>>> >>>>>> === code begin === >>>>>> >>>>>> const >>>>>>    MyStr = 'abc' >>>>>>    MyConst1: AnsiString = MyStr; >>>>>>    MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]); >>>>>> >>>>>> >>>>>> === code end === >>>>>> >>>>> Yes it works, but I must define 2 constants (MyStr and MyConst1), >>>>> which is not so nice ;-) >>>>> >>>>> It would be nice to have support for true constants: >>>>> >>>>> const >>>>>    MyConst1 = 'abc' ; >>>>>    MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]); >>>>> >>>>> But may be that there are technical reasons why it is problematic >>>>> (may >>>>> be that true constants are stored in another memory locations, which >>>>> can not be easy addressed) >>>> >>>> Yes, that's one of possible reasons. >>>> >>>> Regarding Length in constant value assignment - remember that >>>> Length is a function. In case of real constants, the call may be >>>> replaced by the compiler with the constant value. However typed >>>> constants may not be constant, so generic replacement throughout >>>> the source code at compile time is not possible (if it appears in >>>> the main body or some function, the length may already be changed >>>> to something else) and selective replacement may result in a >>>> behaviour not expected by the user. The only questionable case is >>>> IMHO the case of {$WRITEABLECONST OFF} - the compiler _might_ be >>>> able to perform the compile-time substition in that case (and thus >>>> allow using Length of such a constant in constant value >>>> assignment), but it doesn't do that in that case either apparently. >>> >>> Yes I have no problem with {$WRITEABLECONST OFF} if it will allow >>> Length(). >>> >>> Somewhere I read (may be in Delphi documentation) that some intristic >>> functions like Low(), High(), Pred() and also Length() etc. can be >>> used in constant expressions because compiler can evaluate them if >>> theirs arguments are also constants. >>> Which is the case in my example. >>> For now {$WRITEABLECONST OFF} does not help ;-) >> >> Yes, that's what I mentioned as well, but it might be changed for >> this particular case. You might create a ticket for that if Delphi >> allows to use Length that way; obviously, you might create such a >> ticket even if Delphi doesn't allow to do that. ;-) >> > I checked it with older Delphi XE and it seems, that Delphi XE does > not support Length() for typed constant also when {$WRITEABLECONST OFF} > > I do not believe that this will be accepted for FPC, so I don not > open new feature request in bug tracker. > > On other side FPC developers read this mailing list so if they > consider this as a useful/doable feature may be that someone will > take look at it I just happened to write a construct like this (in Delphi): const   X_0: array[0..4276] of SmallInt = (.....   MAP: array['0'..'9'] of TSomething = (     (Samples: @X_0; Count: Length(X_0)), ...

In FPC is possible also (with "array of AnsiChar"):

    MyConst1: array[0..2] of AnsiChar = 'abc';
    MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1);

(but it does not work with plain "AnsiString" as mentioned above)

-Laco.

Reply by email

LacaK
to LacaK: Yes, you are right. That ^ compiles under FPC 3.0 but not under FPC 3.2 I have updated…

Hello,

this compiles under FPC 3.0.4

const
   s: AnsiString = 'abc';
   p: pointer = @s[1];

but not under FPC 3.2.0
(I checked old Delphi XE and there it does not compile also)

Is it regression bug or not?

-Laco.

Show quoted text 20 lines
>> Thank you, yes it works. I have used: >> >> const >>    MyConst1: AnsiString = 'abc' >>    MyConst2: TMyRec = (a: @MyConst1[1]); > > It doesn't compile with fpc 3.2.0 (I'm trying, without success so > far, your open62541 translation). > Yes, you are right. That ^ compiles under FPC 3.0 but not under FPC 3.2 I have updated test program (now compiles also under FPC 3.2) Thanks -Laco.

Reply by email

Sven Barth
to Marc Weustink: I just happened to write a construct like this (in Delphi): const X_0: array[0..4276] of…
Marc Weustink wrote 86 lines
On 4-12-2020 13:01, LacaK via fpc-pascal wrote: > > Dňa 2.12.2020 o 16:09 Tomas Hajny via fpc-pascal napísal(a): >> On 2020-12-02 16:01, LacaK via fpc-pascal wrote: >>> Dňa 2.12.2020 o 13:55 Tomas Hajny via fpc-pascal napísal(a): >>>> On 2020-12-01 11:39, Ladislav Karrach via fpc-pascal wrote: >>>>>> >>>>>> Because MyConst1 is not an *untyped* constant. Only untyped >>>>>> constants can be used in constant expressions (a pointer to >>>>>> something can be considered an untyped constant). >>>>>> >>>>>> The following might work though I did not test it: >>>>>> >>>>>> === code begin === >>>>>> >>>>>> const >>>>>>    MyStr = 'abc' >>>>>>    MyConst1: AnsiString = MyStr; >>>>>>    MyConst2: TMyRec = (l: Length(MyStr); a: @MyConst1[1]); >>>>>> >>>>>> >>>>>> === code end === >>>>>> >>>>> Yes it works, but I must define 2 constants (MyStr and MyConst1), >>>>> which is not so nice ;-) >>>>> >>>>> It would be nice to have support for true constants: >>>>> >>>>> const >>>>>    MyConst1 = 'abc' ; >>>>>    MyConst2: TMyRec = (l: Length(MyConst1); a: @MyConst1[1]); >>>>> >>>>> But may be that there are technical reasons why it is problematic >>>>> (may >>>>> be that true constants are stored in another memory locations, which >>>>> can not be easy addressed) >>>> >>>> Yes, that's one of possible reasons. >>>> >>>> Regarding Length in constant value assignment - remember that >>>> Length is a function. In case of real constants, the call may be >>>> replaced by the compiler with the constant value. However typed >>>> constants may not be constant, so generic replacement throughout >>>> the source code at compile time is not possible (if it appears in >>>> the main body or some function, the length may already be changed >>>> to something else) and selective replacement may result in a >>>> behaviour not expected by the user. The only questionable case is >>>> IMHO the case of {$WRITEABLECONST OFF} - the compiler _might_ be >>>> able to perform the compile-time substition in that case (and thus >>>> allow using Length of such a constant in constant value >>>> assignment), but it doesn't do that in that case either apparently. >>> >>> Yes I have no problem with {$WRITEABLECONST OFF} if it will allow >>> Length(). >>> >>> Somewhere I read (may be in Delphi documentation) that some intristic >>> functions like Low(), High(), Pred() and also Length() etc. can be >>> used in constant expressions because compiler can evaluate them if >>> theirs arguments are also constants. >>> Which is the case in my example. >>> For now {$WRITEABLECONST OFF} does not help ;-) >> >> Yes, that's what I mentioned as well, but it might be changed for >> this particular case. You might create a ticket for that if Delphi >> allows to use Length that way; obviously, you might create such a >> ticket even if Delphi doesn't allow to do that. ;-) >> > I checked it with older Delphi XE and it seems, that Delphi XE does > not support Length() for typed constant also when {$WRITEABLECONST OFF} > > I do not believe that this will be accepted for FPC, so I don not > open new feature request in bug tracker. > > On other side FPC developers read this mailing list so if they > consider this as a useful/doable feature may be that someone will > take look at it I just happened to write a construct like this (in Delphi): const   X_0: array[0..4276] of SmallInt = (.....   MAP: array['0'..'9'] of TSomething = (     (Samples: @X_0; Count: Length(X_0)), ...

That works, because the size of the *type* is known at compile time. String data however is not part of the type, it's content.

Regards,
Sven

Reply by email