最近我将大量的C ++代码移植到Delphi(超过1mb的C代码)。代码已满,带有指针。尽管项目编译和99%的时间都运行良好,我不时会看到一些奇怪的结果,这让我觉得可能存在指针处理的错误 - 事实上,我已经找到了一对。问题是,如果没有编译器的任何线索/提示,它们很难被追踪。
对于这种情况,也许你有一些提示:
var
a: PSingle;
GetMem(a, SizeOf(Single));
a^ := 1.1;
// Call func declared as - someFunc(aIn: PSingle);
someFunc(@a); // <<-- Bug here. I mistakely added @ while porting.
// someFunc needs PSingle, but gets a PPSingle instead
在示例中,插入了错误的@
。程序不会崩溃,只处理错误的数据并继续运行。我需要一种方法来找到这样的情况:“指向值的指针”而不是“指向值的指针”。
如何跟踪这些指针错误?
答案 0 :(得分:12)
&#34;键入@运算符&#34;编译器选项旨在准确检测那种错误。当它被禁用时,表达式@a
具有类型Pointer
,它与所有指针类型兼容。启用该选项,同一表达式的类型为^PSingle
,与预期的PSingle
不兼容。
我建议在所有项目中启用该选项;令我感到困惑的是,德尔福并没有始终将该选项作为默认选项。
您可以使用$T+
和$T-
编译器指令修改代码中该选项的状态。
您可以做的另一件事是将代码转换为使用更多惯用的Delphi。例如,通过引用而不是指针值传递参数。更改参数的定义:
procedure someFunc(var arg: Single);
使用该声明,传递@a
将是编译器将找到并禁止的错误。您可以改为通过a^
,或者甚至可以完全摆脱指针,只需将a
声明为普通Single
而不是PSingle
。
仅仅因为原始代码是用C和C风格的C ++编写的,它并不代表你的Delphi代码看起来像它。
答案 1 :(得分:0)
问题在于:
someFunc(@a);
您正在添加一个指向指针而不是指针的指针。
让我举个例子:
用途 数学;
function Somefunc(value:pSingle):Single; 开始 结果:=(值^ + 1.1) 端;
procedure TForm23.FormCreate(Sender: TObject);
var
a: pSingle;
b: Single;
begin
GetMem(a, SizeOf(Single));
a^ := 1.1;
//Example 1:
b := Somefunc(a);
Caption := BoolToStr(CompareValue(2.2, b, 0.00001) = 0., True); //Caption: True
//Example 2:
b := Somefunc(@a); //NOTE @a
Caption := BoolToStr(CompareValue(1.1, b, 0.00001) = 0., True); //Caption: True
FreeMem(a);
end;
正如您在第一个示例中看到的那样,实际值已更改,而在示例2中,值og a保持不变,因为您将指针解析为指针,因此它是您指向的指针而不是值。