Lazarus

Free Pascal => General => Topic started by: 440bx on July 06, 2021, 06:48:44 am

Title: widechar constant declaration
Post by: 440bx on July 06, 2021, 06:48:44 am
Hello,

in C header files it is common to see a declaration such as :
Code: C  [Select][+][-]
  1. #define ACCESS_DS_SOURCE_W L"DS"
  2.  

The equivalent in Pascal (but not accepted by the compiler) is :
Code: Pascal  [Select][+][-]
  1. const
  2.   ACCESS_DS_SOURCE_W                 = widechar('DS');
  3.  
It doesn't like the widechar typecast on what it considers a string and not just a character.

A workaround is to define the constant as a typed constant to a pwidechar but, that isn't semantically quite the same as the C definition.

My question is: is there some way to declare that 'DS' constant to be widechar without using a typed constant (which is a variable, not a compiler constant) ?

Thank you for your help.
Title: Re: widechar constant declaration
Post by: Zvoni on July 06, 2021, 08:37:46 am
WideString instead of WideChar?
Title: Re: widechar constant declaration
Post by: 440bx on July 06, 2021, 09:58:10 am
WideString instead of WideChar?
Thank you.  That looks like it will work when using FPC.

By any chance, do you know any solution that would work with Delphi 2 as well ? (Delphi 2 doesn't support "widestring")
Title: Re: widechar constant declaration
Post by: marcov on July 06, 2021, 09:58:21 am
Code: Pascal  [Select][+][-]
  1. const x = unicodestring('DS');
  2. begin
  3.  
  4. end.

As for D2, I don't know. widechar('D')+widechar('S') ? Typecast to an array[0..1] of widechar ?

Title: Re: widechar constant declaration
Post by: 440bx on July 06, 2021, 10:14:16 am
Code: Pascal  [Select][+][-]
  1. const x = unicodestring('DS');
  2. begin
  3.  
  4. end.

As for D2, I don't know. widechar('D')+widechar('S') ? Typecast to an array[0..1] of widechar ?
Thank you Marcov.  I tried both of your suggestions and unfortunately Delphi 2 doesn't like either one of them.  They were definitely worth a try.

Now, I have another question.  Is there a difference between typecasting the constant as a unicodestring instead of a widestring ? FPC accepts either and, that makes me wonder what exactly, if any, is the difference. 
Title: Re: widechar constant declaration
Post by: marcov on July 06, 2021, 10:34:25 am
Now, I have another question.  Is there a difference between typecasting the constant as a unicodestring instead of a widestring ? FPC accepts either and, that makes me wonder what exactly, if any, is the difference.

On Windows, widestring is a COM backed version of unicodestring. Some operations(ref counting/allocation) might be slower.

But I think constants and chars are not really operations, so this usage will be the same. Still it is a good habit to only use widestring for COM related purposes.
Title: Re: widechar constant declaration
Post by: 440bx on July 06, 2021, 10:50:48 am
Thank you Marco, I appreciate the explanation.
Title: Re: widechar constant declaration
Post by: Thaddy on July 06, 2021, 11:05:05 am
IIRC D2 does only support PWideChar as "string" type, but not unicodestring nor widestring.
Title: Re: widechar constant declaration
Post by: PascalDragon on July 06, 2021, 03:45:09 pm
The equivalent in Pascal (but not accepted by the compiler) is :
Code: Pascal  [Select][+][-]
  1. const
  2.   ACCESS_DS_SOURCE_W                 = widechar('DS');
  3.  

No, that is not the equivalent, because WideChar is only a single character. It would be as if you'd write (wchar_t)'DS' in C.

A workaround is to define the constant as a typed constant to a pwidechar but, that isn't semantically quite the same as the C definition.

The closest would be to simply declare it as an untyped string constant (ACCESS_DS_SOURCE_W = 'DS'). When you assign it to a PWideChar parameter/variable the compiler will handle that accordingly (Note: Delphi 2 might not).
Title: Re: widechar constant declaration
Post by: 440bx on July 06, 2021, 11:18:56 pm
The equivalent in Pascal (but not accepted by the compiler) is :
Code: Pascal  [Select][+][-]
  1. const
  2.   ACCESS_DS_SOURCE_W                 = widechar('DS');
  3.  

No, that is not the equivalent, because WideChar is only a single character. It would be as if you'd write (wchar_t)'DS' in C.
You're right.  That's just the closest I could think of to inform the compiler that the string is made of wide chars.

A workaround is to define the constant as a typed constant to a pwidechar but, that isn't semantically quite the same as the C definition.

The closest would be to simply declare it as an untyped string constant (ACCESS_DS_SOURCE_W = 'DS'). When you assign it to a PWideChar parameter/variable the compiler will handle that accordingly (Note: Delphi 2 might not).
My concern with declaring it as an untyped constant is those "invisible" compiler "preferences" that may not always match what the API prefers.

Thank you for the correction and additional information.
Title: Re: widechar constant declaration
Post by: engkin on July 08, 2021, 05:58:56 am
Now, I have another question.  Is there a difference between typecasting the constant as a unicodestring instead of a widestring ? FPC accepts either and, that makes me wonder what exactly, if any, is the difference.

When the compiler produce WideString constant, it will be smaller in size. It only has the length in *bytes* preceding the text. While UnicodeString constant has in addition to the length in *codepoints*, three other values: codepage, element size, and reference count.

More over, the length is 4 bytes for WideString regardless of 32/64 bit application. When constant length is needed,  a shift right (division by 2) is produced by the compiler to convert from bytes to codepoints.
Title: Re: widechar constant declaration
Post by: 440bx on July 08, 2021, 06:28:14 am
Thank you Engkin.  Those are really important things to know about Widestring and UnicodeString.
Title: Re: widechar constant declaration
Post by: PascalDragon on July 08, 2021, 08:59:59 am
Thank you Engkin.  Those are really important things to know about Widestring and UnicodeString.

In addition to what Engkin wrote: WideString as such only exists on the Windows targets, while on all other systems WideString is simply an alias to UnicodeString and thus the constants will behave the same there no matter if you use WideString or UnicodeString (I'm aware that marcov already said something similar, I just wanted to highlight this in context of the constants again).
Title: Re: widechar constant declaration
Post by: 440bx on July 08, 2021, 10:33:14 am
In addition to what Engkin wrote: WideString as such only exists on the Windows targets, while on all other systems WideString is simply an alias to UnicodeString and thus the constants will behave the same there no matter if you use WideString or UnicodeString (I'm aware that marcov already said something similar, I just wanted to highlight this in context of the constants again).
Thank you PascalDragon.  Definitely those are important things to know too.
Title: Re: widechar constant declaration
Post by: Remy Lebeau on July 08, 2021, 06:26:30 pm
IIRC D2 does only support PWideChar as "string" type, but not unicodestring nor widestring.

Delphi 2 supported short strings (String[N]), long strings (AnsiString), and P(Ansi|Wide)Char null-terminated character pointers.

AnsiString was added in Delphi 2.

WideString was added in Delphi 3.

UnicodeString was added in Delphi 2009.

More over, the length is 4 bytes for WideString regardless of 32/64 bit application. When constant length is needed,  a shift right (division by 2) is produced by the compiler to convert from bytes to codepoints.

More accurately, dividing the byte length by 2 (aka sizeof(WideChar)) will produce a count of codeunits, not codepointsWideString is encoded using UTF-16 (or UCS-2 prior to Win2k), so the character length of a UTF-16/UCS-2 string is the number of 16-bit units it holds, not the number of Unicode codepoints they represent.  In UTF-16, it takes two 16-bit units to represent codepoints > U+FFFF.
Title: Re: widechar constant declaration
Post by: PascalDragon on July 09, 2021, 09:03:02 am
IIRC D2 does only support PWideChar as "string" type, but not unicodestring nor widestring.

Delphi 2 supported short strings (AnsiString[N]), long strings (AnsiString), PAnsiChar, and PWideChar.

Short strings are String[N], not AnsiString[N], cause they come from TP times. ;)
TinyPortal © 2005-2018