Sign in Join

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

Mailing lists / fpc-pascal / 2016-06

Incompatible types: got "SYSTEM.PChar" expected "SYSTEM.PChar"

4 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

José Mejuto

Hello,

I have a lot of constant strings and some array of records that should be initialized in one field with one of this entries, so I found two solutions, one is create a symbol for each string, something like:

const
   TMyStringSymbol='String one';

But also I need to be able to enumerate all of them at runtime, so I wrote an array and initialize it at compile time (this also produces less symbol pollution for the compiler):

const
   TMyStrings: array [0..1] of pchar = (
     'String One','String Two');

As I need this names in other places I try to create a record and initialize it at runtime using the pchar of the previous array, and here is the problem:

-----------------------
program testpossiblebug;
type
   TFirstRecord=record
     Ident: pchar;
   end;
const
   TSomePcharArray: array [0..1] of pchar = ( 'pcharONE','pcharTWO');
{$DEFINE THISDONTCOMPILE}
   TConstRecord: TFirstRecord = (
   {$IFDEF THISDONTCOMPILE}
     Ident: TSomePcharArray[1]
   {$ELSE}
     Ident: @TSomePcharArray[1]
   {$ENDIF}
   );
var
   R: TFirstRecord;
begin
   R:=TConstRecord;
   {$IFDEF THISDONTCOMPILE}
   writeln(R.Ident);
   {$ELSE}
   writeln(PPchar(R.Ident)^);
   {$ENDIF}
end.
------------------------

This does not compile and outputs the funny error in the subject. I think it should compile as information is static and previously defined, but if it is indeed an error by my side maybe the error message should be a bit different :-?

To test the example, define or undefine the "THISDONTCOMPILE", with it defined it does not compile, without it it compiles and the modified writeln shows the expected pchar string.

Should I report it ?

Sven Barth
to José Mejuto
"José Mejuto" wrote 35 lines
----------------------- program testpossiblebug; type TFirstRecord=record Ident: pchar; end; const TSomePcharArray: array [0..1] of pchar = ( 'pcharONE','pcharTWO'); {$DEFINE THISDONTCOMPILE} TConstRecord: TFirstRecord = ( {$IFDEF THISDONTCOMPILE} Ident: TSomePcharArray[1] {$ELSE} Ident: @TSomePcharArray[1] {$ENDIF} ); var R: TFirstRecord; begin R:=TConstRecord; {$IFDEF THISDONTCOMPILE} writeln(R.Ident); {$ELSE} writeln(PPchar(R.Ident)^); {$ENDIF} end. ------------------------ This does not compile and outputs the funny error in the subject. I think

it should compile as information is static and previously defined, but if it is indeed an error by my side maybe the error message should be a bit different :-?

To test the example, define or undefine the "THISDONTCOMPILE", with it

defined it does not compile, without it it compiles and the modified writeln shows the expected pchar string.

Should I report it ?

One can only use untyped constants to initialize other constants or variables in their declarations. The TsomePCharArray is a typed constant, thus not suitable for assignments (a pointer to it's element is however legal as you noticed).

Don't know how easy it would be to print a better error message...

Regards,
Sven

José Mejuto
to Sven Barth
Sven Barth wrote 13 lines
> {$DEFINE THISDONTCOMPILE} > TConstRecord: TFirstRecord = ( > {$IFDEF THISDONTCOMPILE} > Ident: TSomePcharArray[1] > {$ELSE} > Ident: @TSomePcharArray[1] > {$ENDIF} > ); One can only use untyped constants to initialize other constants or variables in their declarations. The TsomePCharArray is a typed constant, thus not suitable for assignments (a pointer to it's element is however legal as you noticed).

Hello,

The strange thing is that if I use a pointer, an integer or any other type instead a Pchar the error message is completely different "Error: Can't read or write variables of this type" which is a bit more informative.

I understand that untyped is the only source for assign a constant to so using @ I get an untyped pointer and the assign is performed, but is there a way to convert a pointer (typed) to untyped one ?

I think that the solution is to pollute the symbol table with a lot of consts, one of each text string.

Thank you for your help and enlightenment.

Sven Barth
to José Mejuto
"José Mejuto" wrote 22 lines
El 09/06/2016 a las 8:04, Sven Barth escribió: >> {$DEFINE THISDONTCOMPILE} >> TConstRecord: TFirstRecord = ( >> {$IFDEF THISDONTCOMPILE} >> Ident: TSomePcharArray[1] >> {$ELSE} >> Ident: @TSomePcharArray[1] >> {$ENDIF} >> ); > One can only use untyped constants to initialize other constants or > variables in their declarations. The TsomePCharArray is a typed > constant, thus not suitable for assignments (a pointer to it's element > is however legal as you noticed). Hello, The strange thing is that if I use a pointer, an integer or any other

type instead a Pchar the error message is completely different "Error: Can't read or write variables of this type" which is a bit more informative.

I understand that untyped is the only source for assign a constant to so

using @ I get an untyped pointer and the assign is performed, but is there a way to convert a pointer (typed) to untyped one ?

Typed and untyped pointer have nothing to do with this. It's about typed and untyped constants. And addresses to variables and typed constants are by definition untyped constants as well.

I think that the solution is to pollute the symbol table with a lot of

consts, one of each text string.

Thank you for your help and enlightenment.

You're welcome.

Regards,
Sven