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

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

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

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 ?

--

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

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

Sven Barth-2

Am 09.06.2016 00:05 schrieb "José Mejuto" <[hidden email]>:
> -----------------------
> 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


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

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

José Mejuto
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 ?

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.

--

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

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

Sven Barth-2

Am 09.06.2016 14:30 schrieb "José Mejuto" <[hidden email]>:
>
> 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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal