By default, FPC (the compiler used by Lazarus) stores "0" (CP_ACP) as the code page for an ansistring (as your first test shows).
Frankly, the default LCL setup pretending CP_ACP = CP_UTF8 breaks a number of standard coding patterns.
Last time i was hit by it was debugging Windows GDI code in Castle Game Engine.
The normal unicodestring := ansistring conversion was broken there,
So i think this LCL choice was never correct and was not even most practical. But - what was done is done.
It was done because it was the only way to keep backward compatibility with previous code (which Delphi didn't care about).
However, for UTF-16 strings the encoding is different (and frankly, should be ignored as long as "char size = 2" is detected.
The code page in an utf-16 string is ignored by the FPC rtl. However, if you assing a constant string in the sourcefile to a unicodestring, and the source file is not written in UTF-16 (I think we don't even support UTF-16 source files), then the compiler must either
a) store the string constant as it appeared in the source file, and convert it at run time to UTF-16, or
b) convert it to UTF-16 at compile time
The compiler nowadays does b), and it's this part that's going wrong if the code page of the source file is not explicitly specified. See
https://wiki.freepascal.org/FPC_Unicode_support#String_constantsThe compiler has to know the code page according to which it should interpret string constants, as it may have to convert them at compile time. Normally, a string constant is interpreted according to the source file codepage. If the source file codepage is CP_ACP, a default is used instead: in that case, during conversions the constant strings are assumed to have code page 28591 (ISO 8859-1 Latin 1; Western European).
To be sure: in what code page is your source file that you are compiling, both in Delphi and in Lazarus?