2016-03-13 100 views
2

這個單元測試用的Free Pascal 3.0成功運行在Delphi模式:何時安全地將UnicodeString強制轉換爲Free Pascal 3字符串?

procedure TFreePascalTests.TestUTF8Decode; 
var 
    Raw: RawByteString; 
    Actual: string; 
begin 
    Raw := UTF8Encode('關於漢語'); 

    Actual := string(UTF8Decode(Raw)); // <--- cast from UnicodeString 

    CheckEquals('關於漢語', Actual); 

    // check Windows ANSI code page 
    CheckEquals(1252, GetACP); 
    // check Free Pascal value (determines how CP_ACP is interpreted) 
    CheckEquals(65001, DefaultSystemCodePage); 
end; 

UTF8Decode返回的UnicodeString。如果沒有硬盤類型轉換爲字符串時,編譯器發出警告不安全的轉換:

警告:隱式字符串類型轉換與潛在的數據丟失,從 「的UnicodeString」到「AnsiString類型」

(與測試Lazarus 1.6/FPCUnit GUITestrunner)

根據http://wiki.freepascal.org/Character_and_string_types#String,字符串類型默認爲AnsiString(如果{$ H +}開關設置爲使用AnsiString而不是ShortString)。

它看起來像Free Pascal將Unicode字符串存儲在AnsiString變量中。 (即使沒有演員表,測試成功)

問題:隨着測試成功,我可以假設使用演員陣容(壓制警告)是安全的,而不會冒數據丟失的風險嗎?

+0

'此單元測試運行成功' - 什麼是您的操作系統默認語言? – GSerg

+0

@GSerg操作系統使用英語作爲默認語言 – mjn

回答

3

由於您仍然將UnicodeString轉換爲AnsiString並且在編譯時未知AnsiString的編碼,所以鑄造通常不安全。警告只會在你明確地做,並且編譯器假定你知道你在做什麼。

如果轉換工作取決於系統上的編碼設置:它是UTF-8,然後Actual包含字符串UTF-8編碼,它可以工作,或者系統上的特定語言環境支持您正在使用的字符。如果您在帶有e的系統上運行此代碼。 G。 CP1250,它會失敗。控制變量是DefaultSystemCodePage。啓動時,它由FPC RTL使用系統編碼進行初始化。但是,有框架(如拼箱)可以覆蓋它並將其設置爲e。 G。 UTF-8。

使用{$modeswitch unicodestrings}除了{$mode delphi}string等於unicodestring,所以編碼將是區域獨立的。

+0

'如果您在具有e的系統上運行此代碼。 G。 CP1250,它會失敗 - 在我的情況下,代碼不會失敗,請參閱我的編輯,其中包含單元測試中的其他環境檢查。看起來Free Pascal 3在模式delphi中使用UTF-8(代碼頁65001)。 – mjn

+0

這個'{$ mode delphi}開始寫(DefaultSystemCodePage);在這裏寫1252。你確定你沒有包含額外的單位嗎? – FPK

+0

是的,很可能FPCUnit(我使用GUI測試運行器)所需的單元之一對此負責。我會在稍後檢查。我的#1嫌犯是LCL單位'Interfaces'。 (這也意味着被測試的代碼只能在FPCUnit中正常工作,因爲它......)+1 – mjn

相關問題