2015-02-12 72 views
1

我已經得到了非常愚蠢的問題... 爲什麼這個代碼:鑄造面值爲PChar類型/ PAnsiChar

PChar('x'); 

原因 「訪問衝突」 錯誤? 編譯器優化?

實施例:

var s: String; 
... 
s := StrPas(PAnsiChar('x')); 

這導致AV在Delphi 5/Delphi的XE

或者這一個:

Windows.MessageBox(0, PChar('x'), PChar('y'), 0); 

這導致AV在Delphi 5,但不是在Delphi XE 在XE中有一個空的MessageBox

控制檯示例:

program Project1; 
{$APPTYPE CONSOLE} 
uses 
    SysUtils, Windows; 
var s: String; 
begin 
    s := StrPas(PChar('xxx')); // EAccessViolation here 
end. 
+0

另一個非常愚蠢的問題是:你使用的是什麼版本的Delphi?任何人如何重現這一點?因爲僅僅這一行就不能編譯。 – 2015-02-12 06:31:21

+0

已更正+示例 我需要將字符串變量更改爲文字以進行測試,並且我有點驚訝...... @David Heffernan這是一個要點xD – 2015-02-12 07:06:02

+3

我想知道。 「x」是一個char字面量嗎?所以只有一個字符?也許這就是我所缺少的。 – 2015-02-12 07:13:41

回答

3
StrPas(PAnsiChar('x')); 

我斷定,'x'作爲一個字符文字而不是一個字符串處理。所以演員表無效。如果是這樣,那麼這將工作,因爲你會期望

StrPas('x'); 

由於隱式轉換。或

StrPas(PAnsiChar(AnsiString('x'))); 

感謝顯式轉換。

我認爲前者可能是首選。文字不需要轉換爲空終止的指針類型。編譯器可以在不投射的情況下發出正確的代碼。演員們總是冒着壓制錯誤的風險。

+0

Ooook ...你說得對。感謝您的解釋! :) 我添加了測試一塊代碼的文字,然後我有點懷疑... – 2015-02-12 07:21:50

+0

德爾福在這裏有點跛腳。全部來源於對字符串和字符使用相同的分隔符。 – 2015-02-12 07:31:19