Sign in Join
Wiki copytemporary

Character and string types: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11Free Pascal supports several **[[Char|character]] and [[String|string]] types**. They range from single ANSI characters to unicode strings and also include pointer types. Differences also apply to encodings and reference counting.
22
33## Character types
44
55### AnsiChar
66
77A variable of type **AnsiChar**, also referred to as **[[Char|char]]**, is exactly 1 byte in size, and contains one "ANSI" (local code page) character.
88
99| |
1010|-----|
1111| a |
1212
1313#### Reference
1414
1515- [FPC AnsiChar documentation](http://www.freepascal.org/docs-html/ref/refsu6.html)
1616- [[Char|Usage Char]]
1717- [Wikipedia:Windows code page#ANSI code page](https://en.wikipedia.org/wiki/Windows_code_page#ANSI_code_page)
1818
1919### WideChar
2020
2121A variable of type **WideChar**, also referred to as **UnicodeChar**, is exactly 2 bytes in size, and usually contains one [[LCL Unicode Support|Unicode]] code point (normally a character) in UTF-16 encoding. Note: it is impossible to encode all Unicode code points in 2 bytes. Therefore, 2 WideChars may be needed to encode a single code point.
2222
2323| | |
2424|-----|-----|
2525| | a |
2626
2727#### References
2828
2929- [FPC WideChar documentation](http://www.freepascal.org/docs-html/ref/refsu7.html)
3030- [UTF-16 information on Wikipedia](https://en.wikipedia.org/wiki/UTF-16)
3131- [[doc:rtl/system/unicodechar.html|RTL UnicodeChar documentation]]
3232
3333## Character-derived types
3434
3535### Array of Char
3636
3737Early Pascal implementations that were in use before 1978 did not support a string type (with the exception of string constants). The only possibility to store strings in variables was the use of arrays of char. This approach has many disadvantages and is no longer recommended. It is, however, still supported to ensure backward-compatibility with ancient code.
3838
3939#### Static Array of Char
4040
4141``` pascal
4242type
4343 TOldString4 = array[0..3] of char;
4444var
4545 aOldString4: TOldString4;
4646begin
4747 aOldString4[0] := 'a';
4848 aOldString4[1] := 'b';
4949 aOldString4[2] := 'c';
5050 aOldString4[3] := 'd';
5151end;
5252```
5353
5454The static array of char has now the content:
5555
5656| | | | |
5757|-----|-----|-----|-----|
5858| a | b | c | d |
5959
6060> **Note:** Unassigned chars can have any content, depending on what was just in memory when the memory for the array was made available.
6161
6262#### Dynamic Array of Char
6363
6464``` pascal
6565var
6666 aOldString: Array of Char;
6767begin
6868 SetLength(aOldString, 5);
6969 aOldString[0] := 'a';
7070 aOldString[1] := 'b';
7171 aOldString[2] := 'c';
7272 aOldString[3] := 'd';
7373end;
7474```
7575
7676The dynamic array of char has now the content:
7777
7878| | | | | |
7979|-----|-----|-----|-----|-----|
8080| a | b | c | d | \#0 |
8181
8282> **Note:** Unassigned chars in dynamic arrays have a content \#0, cause empty positions of all dynamic arrays are initially initialised with 0 (or \#0, or nil, or ...)
8383
8484### PChar
8585
8686A variable of type **[[PChar]]** is basically a pointer to a **Char** type, but allows additional operations. PChars can be used to access C-style [null-terminated strings](http://en.wikipedia.org/wiki/Null-terminated_string), e.g. in interaction with certain OS libraries or third-party software.
8787
8888| | | | |
8989|-----|-----|-----|-----|
9090| a | b | c | \#0 |
9191| ^ | | | |
9292
9393#### Reference
9494
9595- [FPC PChar documentation](http://www.freepascal.org/docs-html/ref/refsu12.html)
9696- [[doc:rtl/sysutils/pcharfunctions.html|PChar related functions]]
9797
9898### PWideChar
9999
100100A variable of type **PWideChar** is a pointer to a WideChar variable.
101101
102102| | | | | | | | |
103103|-----|-----|-----|-----|-----|-----|-----|-----|
104104| | a | | b | | c | \#0 | \#0 |
105105| ^ | | | | | | | |
106106
107107#### Reference
108108
109109- [[doc:rtl/system/pwidechar.html|RTL PWideChar documentation]]
110110
111111## String types
112112
113113### String
114114
115115The type **String** may refer to **ShortString** or **AnsiString**, depending from the [{\$H} switch](http://www.freepascal.org/docs-html/prog/progsu25.html#x32-310001.2.25). If the switch is off ({\$H-}) then any string declaration will define a **ShortString**. It size will be 255 chars, if not otherwise specified. If it is on ({\$H+}) **string** without length specifier will define an **AnsiString**, otherwise a **ShortString** with specified length. In **mode delphiunicode** **String'' is**UnicodeString'''.
116116
117117#### Reference
118118
119119- [[String|Usage String]].
120120- [[doc:rtl/sysutils/stringfunctions.html|String functions]]
121121- [[doc:rtl/strutils/index-5.html|Reference for unit 'strutils': Procedures and functions]]
122122
123123### ShortString
124124
125125Short strings have a maximum length of 255 characters with the implicit [[FPC Unicode support|codepage]] CP_ACP. The length is stored in the character at index 0. A short string of 255 characters uses 256 bytes of memory (one byte for the length specification and 255 bytes for characters).
126126
127127| | | | |
128128|-----|-----|-----|-----|
129129| \#3 | a | b | c |
130130
131131#### Reference
132132
133133- [FPC Single-byte String types documentation](https://www.freepascal.org/docs-html/ref/refsu9.html)
134134
135135### AnsiString
136136
137137Ansistrings are strings that have no length limit. They are [reference counted](http://en.wikipedia.org/wiki/Reference_counting) and are guaranteed to be [null terminated](http://en.wikipedia.org/wiki/Null-terminated_string). Internally, a variable of type **AnsiString** is treated as a pointer: the actual content of the string is stored on the heap, as much memory as needed to store the string content is allocated.
138138
139-<table>
140139<tbody>
141-<tr>
142-<td style="width: 8%;"></td>
143-<td style="width: 8%;"></td>
144-<td style="width: 8%;"></td>
145-<td style="width: 8%;"></td>
146-<td style="width: 8%;"></td>
147-<td style="width: 8%;"></td>
148-<td style="width: 8%;"></td>
149-<td style="width: 8%;"></td>
150-<td style="width: 8%;">a</td>
151-<td style="width: 8%;">b</td>
152-<td style="width: 8%;">c</td>
153-<td style="width: 8%;">#0</td>
154-</tr>
155-<tr>
156-<td colspan="4" style="width: 16%;">RefCount</td>
157-<td colspan="4" style="width: 16%;">Length</td>
158-<td></td>
159-<td></td>
160-<td></td>
161-<td></td>
162-</tr>
140+
163141</tbody>
164-</table>
165142
166143On 64-bit targets, fields RefCount/Length consume 8 bytes each, not 4.
167144
168145An AnsiString type may also have a compile-time code page since FPC 2.7.1; a missing value defaults to `DefaultSystemCodePage`. A value of `CP_NONE` results in **`RawBytestring`** and a value of `CP_UTF8` results in **`UTF8String`**.
169146
170147#### Reference
171148
172149- [FPC Single-byte String types documentation](https://www.freepascal.org/docs-html/ref/refsu9.html)
173150
174151### UnicodeString
175152
176153Like **AnsiStrings**, **UnicodeStrings** are reference counted, null-terminated arrays, but they are implemented as arrays of **WideChars** instead of regular **Chars**.
177154
178155> **Note:** The UnicodeString naming is a bit ambiguous but probably due to its use in Delphi on Windows, where the OS uses UTF16 encoding; it's not the only string type that can hold Unicode string data (see also UTF8String)...
179156
180-<table>
181157<tbody>
182-<tr>
183-<td style="width: 7%;"></td>
184-<td style="width: 7%;"></td>
185-<td style="width: 7%;"></td>
186-<td style="width: 7%;"></td>
187-<td style="width: 7%;"></td>
188-<td style="width: 7%;"></td>
189-<td style="width: 7%;"></td>
190-<td style="width: 7%;"></td>
191-<td style="width: 7%;"></td>
192-<td style="width: 7%;">a</td>
193-<td style="width: 7%;"></td>
194-<td style="width: 7%;">b</td>
195-<td style="width: 7%;"></td>
196-<td style="width: 7%;">c</td>
197-<td style="width: 7%;">#0</td>
198-<td style="width: 7%;">#0</td>
199-</tr>
200-<tr>
201-<td colspan="4" style="width: 16%;">RefCount</td>
202-<td colspan="4" style="width: 16%;">Length</td>
203-<td></td>
204-<td></td>
205-<td></td>
206-<td></td>
207-<td></td>
208-<td></td>
209-<td></td>
210-<td></td>
211-</tr>
158+
212159</tbody>
213-</table>
214160
215161On 64-bit targets, fields RefCount/Length consume 8 bytes each, not 4.
216162
217163#### Reference
218164
219165- [FPC Multi-byte String types documentation](http://www.freepascal.org/docs-html/ref/refsu10.html)
220166
221167### UTF8String
222168
223169In FPC 2.6.5 and below the type **UTF8String** was an alias to the type **AnsiString**. In FPC 2.7.1 and above it is defined as `UTF8String = type AnsiString(CP_UTF8);`
224170
225171It is meant to contain UTF-8 encoded strings (i.e. unicode data) ranging from 1..4 bytes per character. Note that **String** can also contain UTF-8 encoded characters.
226172
227173#### Reference
228174
229175- [FPC UTF8String documentation](https://www.freepascal.org/docs-html/ref/refsu9.html#x32-400003.2.4)
230176
231177### UTF16String
232178
233179The type **UTF16String** is an alias to the type **WideString**. In the LCL unit *lclproc* it is an alias to **UnicodeString**.
234180
235181#### Reference
236182
237183- [[doc:lcl/lclproc/utf16string.html|LCL UTF16String documentation]]
238184
239185### WideString
240186
241187Variables of type **[[Widestrings|WideString]]** (used to represent unicode character strings in COM applications) resemble those of type **UnicodeString**, but unlike them they are not reference-counted. On Windows they are allocated with a special windows function which allows them to be used for OLE automation.
242188
243189WideStrings consist of COM compatible UTF16 encoded bytes on Windows machines (UCS2 on Windows 2000), and they are encoded as plain UTF16 on Linux, Mac OS X and iOS.
244190
245-<table>
246191<tbody>
247-<tr>
248-<td style="width: 8%;"></td>
249-<td style="width: 8%;"></td>
250-<td style="width: 8%;"></td>
251-<td style="width: 8%;"></td>
252-<td style="width: 8%;"></td>
253-<td style="width: 8%;">a</td>
254-<td style="width: 8%;"></td>
255-<td style="width: 8%;">b</td>
256-<td style="width: 8%;"></td>
257-<td style="width: 8%;">c</td>
258-<td style="width: 8%;">#0</td>
259-<td style="width: 8%;">#0</td>
260-</tr>
261-<tr>
262-<td colspan="4" style="width: 16%;">Length</td>
263-<td></td>
264-<td></td>
265-<td></td>
266-<td></td>
267-<td></td>
268-<td></td>
269-<td></td>
270-<td></td>
271-</tr>
192+
272193</tbody>
273-</table>
274194
275195#### Reference
276196
277197- [FPC Multi-byte String types documentation](http://www.freepascal.org/docs-html/ref/refsu10.html)
278198
279199## String-derived types
280200
281201### PShortString
282202
283203A variable of type **PShortString** is a pointer that points to the first byte of a **ShortString**-type variable (which defines the length of the ShortString).
284204
285205| | | | |
286206|-----|-----|-----|-----|
287207| \#3 | a | b | c |
288208| ^ | | | |
289209
290210#### Reference
291211
292212- [[doc:rtl/system/pshortstring.html|RTL PShortString documentation]]
293213
294214### PAnsiString
295215
296216Variables of type **PAnsiString** are pointers to **AnsiString**-type variables. However, unlike **PShortString**-type variables they don't point to the first byte of the header, but to the first **char** of the **AnsiString**.
297217
298-<table>
299218<tbody>
300-<tr>
301-<td style="width: 8%;"></td>
302-<td style="width: 8%;"></td>
303-<td style="width: 8%;"></td>
304-<td style="width: 8%;"></td>
305-<td style="width: 8%;"></td>
306-<td style="width: 8%;"></td>
307-<td style="width: 8%;"></td>
308-<td style="width: 8%;"></td>
309-<td style="width: 8%;">a</td>
310-<td style="width: 8%;">b</td>
311-<td style="width: 8%;">c</td>
312-<td style="width: 8%;">#0</td>
313-</tr>
314-<tr>
315-<td colspan="4" style="width: 16%;">RefCount</td>
316-<td colspan="4" style="width: 16%;">Length</td>
317-<td style="width: 8%;">^</td>
318-<td></td>
319-<td></td>
320-<td></td>
321-</tr>
219+
322220</tbody>
323-</table>
324221
325222#### Reference
326223
327224- [[doc:rtl/system/pansistring.html|RTL PAnsiString documentation]]
328225
329226### PUnicodeString
330227
331228Variables of type **PUnicodeString** are pointers to variables of type **UnicodeString**.
332229
333-<table>
334230<tbody>
335-<tr>
336-<td style="width: 7%;"></td>
337-<td style="width: 7%;"></td>
338-<td style="width: 7%;"></td>
339-<td style="width: 7%;"></td>
340-<td style="width: 7%;"></td>
341-<td style="width: 7%;"></td>
342-<td style="width: 7%;"></td>
343-<td style="width: 7%;"></td>
344-<td style="width: 7%;"></td>
345-<td style="width: 7%;">a</td>
346-<td style="width: 7%;"></td>
347-<td style="width: 7%;">b</td>
348-<td style="width: 7%;"></td>
349-<td style="width: 7%;">c</td>
350-<td style="width: 7%;">#0</td>
351-<td style="width: 7%;">#0</td>
352-</tr>
353-<tr>
354-<td colspan="4" style="width: 16%;">RefCount</td>
355-<td colspan="4" style="width: 16%;">Length</td>
356-<td style="width: 7%;">^</td>
357-<td></td>
358-<td></td>
359-<td></td>
360-<td></td>
361-<td></td>
362-<td></td>
363-<td></td>
364-</tr>
231+
365232</tbody>
366-</table>
367233
368234#### Reference
369235
370236- [[doc:rtl/system/punicodestring.html|RTL PUnicodeString documentation]]
371237
372238### PWideString
373239
374240Variables of type **PWideString** are pointers. They point to the first char of a **WideString**-typed variable.
375241
376-<table>
377242<tbody>
378-<tr>
379-<td style="width: 8%;"></td>
380-<td style="width: 8%;"></td>
381-<td style="width: 8%;"></td>
382-<td style="width: 8%;"></td>
383-<td style="width: 8%;"></td>
384-<td style="width: 8%;">a</td>
385-<td style="width: 8%;"></td>
386-<td style="width: 8%;">b</td>
387-<td style="width: 8%;"></td>
388-<td style="width: 8%;">c</td>
389-<td style="width: 8%;">#0</td>
390-<td style="width: 8%;">#0</td>
391-</tr>
392-<tr>
393-<td colspan="4" style="width: 16%;">Length</td>
394-<td style="width: 8%;">^</td>
395-<td></td>
396-<td></td>
397-<td></td>
398-<td></td>
399-<td></td>
400-<td></td>
401-<td></td>
402-</tr>
243+
403244</tbody>
404-</table>
405245
406246#### Reference
407247
408248- [[doc:rtl/system/pwidestring.html|RTL PWideString documentation]]
409249
410250## String constants
411251
412252If you use only English (ASCII) constants your strings work the same with all types, on all platforms and all compiler versions. Non English strings can be loaded via resourcestrings or from files. If you want to use non English strings in code then you should read further.
413253
414254There are various encodings for non English strings. By default Lazarus saves Pascal files as **UTF-8 without BOM**. UTF-8 supports the full Unicode range. That means all string constants are stored in UTF-8. Lazarus also supports to change the encoding of a file to other encoding, for example under Windows your local codepage. The Windows codepage is limited to your current language group.
415255
416256| String Type, UTF-8 Source | With `{$codepage utf8}`? | FPC ≤ 2.6.5 | FPC ≥ 2.7.1 | FPC ≤ 2.7.1, [[Unicode Support in Lazarus|UTF8 as default CodePage]] |
417257|----|----|----|----|----|
418-| <tt>AnAnsiString:='ãü'; | No | Needs UTF8ToAnsi in RTL/WinAPI. Ok in LCL | Needs UTF8ToAnsi in RTL/WinAPI. Ok in LCL | Ok in RTL/W-WinAPI/LCL. Needs UTF8ToWinCP in A-WinAPI. |
419-| <tt>AnAnsiString:='ãü'; | Yes | System cp ok in RTL/WinAPI. Needs SysToUTF8 in LCL | Ok in RTL/WinAPI/LCL. Mixing causes conversion. | Ok in RTL/W-WinAPI/LCL. Needs UTF8ToWinCP in A-WinAPI |
420-| <tt>AnUnicodeString:='ãü'; | No | Wrong everywhere | Wrong everywhere | Wrong everywhere |
421-| <tt>AnUnicodeString:='ãü'; | Yes | System cp ok in RTL/WinAPI. Needs UTF8Encode in LCL | Ok in RTL/WinAPI/LCL.Mixing causes conversion. | Ok in RTL/W-WinAPI/LCL. Needs UTF8ToWinCP in A-WinAPI |
422-| <tt>AnUTF8String:='ãü'; | No | Same as AnsiString | Wrong everywhere | Wrong everywhere |
423-| <tt>AnUTF8String:='ãü'; | Yes | Same as AnsiString | Ok in RTL/WinAPI/LCL. Mixing causes conversion. | Ok in RTL/W-WinAPI/LCL. Needs UTF8ToWinCP in A-WinAPI. |
258+| AnAnsiString:='ãü'; | No | Needs UTF8ToAnsi in RTL/WinAPI. Ok in LCL | Needs UTF8ToAnsi in RTL/WinAPI. Ok in LCL | Ok in RTL/W-WinAPI/LCL. Needs UTF8ToWinCP in A-WinAPI. |
259+| AnAnsiString:='ãü'; | Yes | System cp ok in RTL/WinAPI. Needs SysToUTF8 in LCL | Ok in RTL/WinAPI/LCL. Mixing causes conversion. | Ok in RTL/W-WinAPI/LCL. Needs UTF8ToWinCP in A-WinAPI |
260+| AnUnicodeString:='ãü'; | No | Wrong everywhere | Wrong everywhere | Wrong everywhere |
261+| AnUnicodeString:='ãü'; | Yes | System cp ok in RTL/WinAPI. Needs UTF8Encode in LCL | Ok in RTL/WinAPI/LCL.Mixing causes conversion. | Ok in RTL/W-WinAPI/LCL. Needs UTF8ToWinCP in A-WinAPI |
262+| AnUTF8String:='ãü'; | No | Same as AnsiString | Wrong everywhere | Wrong everywhere |
263+| AnUTF8String:='ãü'; | Yes | Same as AnsiString | Ok in RTL/WinAPI/LCL. Mixing causes conversion. | Ok in RTL/W-WinAPI/LCL. Needs UTF8ToWinCP in A-WinAPI. |
424264
425265- W-WinAPI = Windows API "W" functions, UTF-16
426266- A-WinAPI = Windows API non "W" functions, 8bit system ("ANSI") code page
427267- System CP = The 8bit system code page of the OS. For example code page [1252](http://en.wikipedia.org/wiki/Windows-1252).
428268
429269``` pascal
430270const
431271 c='ãü';
432272 cstring: string = 'ãü'; // see AnAnsiString:='ãü';
433273var
434274 s: string;
435275 u: UnicodeString;
436276begin
437277 s:=c; // same as s:='ãü';
438278 s:=cstring; // does not change encoding
439279 u:=c; // same as u:='ãü';
440280 u:=cstring; // fpc 2.6.1: converts from system cp to UTF-16, fpc 2.7.1+: depends on encoding of cstring
441281end;
442282```
443283
444284The rules for conversion are laid out in a ["Code page conversions"](https://freepascal.org/docs-html/ref/refsu9.html#x32-380003.2.4) section in the FPC manual. The basic point is that assigning an AnsiString (including the `CP_UTF8` specialization) to another AnsiString converts what is in the source to match the code page of the target string. A quirk for compatibility with presumably fpc ≤ 2.6.5 is that no such conversion will be done if one matches the source code CP and the other matches the system CP. In this case, forced (likely incorrect) interpretation as the target code page will occur.
445285
446286## See also
447287
448288- [[FPC Unicode support]]
449289- [[LCL Unicode Support]]
450290- [[TStringList-TStrings Tutorial]]
451291- [A Brief History of Strings](http://web.archive.org/web/20151125114234/http://www.codexterity.com/delphistrings.htm)
452292
453293---
454294*From the Free Pascal wiki, page "Character and string types", as it stood on 2023-12-14 after a change by Coz, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history