ave*_*ore 29 delphi delphi-2007 compiler-warnings
我刚刚调试了一个函数,它返回一个让我担心的字符串.我一直认为返回字符串的函数的隐式Result变量在函数调用开始时将为空,但以下(简化)代码产生了意外的结果:
function TMyObject.GenerateInfo: string;
procedure AppendInfo(const AppendStr: string);
begin
if(Result > '') then
Result := Result + #13;
Result := Result + AppendStr;
end;
begin
if(ACondition) then
AppendInfo('Some Text');
end;
Run Code Online (Sandbox Code Playgroud)
多次调用此函数导致:
"Some Text"
Run Code Online (Sandbox Code Playgroud)
第一次,
"Some Text"
"Some Text"
Run Code Online (Sandbox Code Playgroud)
第二次,
"Some Text"
"Some Text"
"Some Text"
Run Code Online (Sandbox Code Playgroud)
第三次等
要修复它,我必须初始化结果:
begin
Result := '';
if(ACondition) then
AppendInfo('Some Text');
end;
Run Code Online (Sandbox Code Playgroud)
是否需要初始化字符串函数结果?为什么(技术上)?为什么编译器不会发出警告"W1035函数的返回值'xxx'可能是未定义的"字符串函数?我是否需要遍历所有代码以确保设置值,因为如果未明确设置结果,则期望函数中的空字符串不可靠?
我在一个新的测试应用程序中对此进行了测试,结果是一样的.
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
S: string;
begin
for i := 1 to 5 do
S := GenerateInfo;
ShowMessage(S); // 5 lines!
end;
Run Code Online (Sandbox Code Playgroud)
Ale*_*lex 33
这不是错误,而是" 功能 ":
对于字符串,动态数组,方法指针或变体结果,效果与在声明的参数之后将函数结果声明为附加var参数的效果相同.换句话说,调用者传递一个额外的32位指针,该指针指向一个返回函数结果的变量.
就是你的
function TMyObject.GenerateInfo: string;
Run Code Online (Sandbox Code Playgroud)
真的是这样的:
procedure TMyObject.GenerateInfo(var Result: string);
Run Code Online (Sandbox Code Playgroud)
注意" var "前缀(不是你想象中的" out "!).
这是此类非直观的,所以它会导致所有类型的代码中的错误.有问题的代码 - 只是此功能结果的一个示例.
查看并投票支持此请求.
我们以前遇到过这种情况,我想可能早在 Delphi 6 或 7 时就遇到过。是的,即使编译器不会给你警告,你确实需要初始化你的字符串 Result 变量,正是出于这个原因你碰到了。该字符串变量是越来越初始化-它没有启动的垃圾参考-但它似乎并没有得到重新初始化时,你指望它。
至于为什么会发生……不确定。这是一个错误,所以它不一定需要一个原因。我们只在循环中重复调用该函数时才看到它发生;如果我们在循环外调用它,它会按预期工作。看起来调用者正在为 Result 变量分配空间(并在重复调用同一个函数时重用它,从而导致错误),而不是函数分配自己的字符串(并在每次调用时分配一个新字符串)。
如果您使用的是短字符串,那么调用者会分配缓冲区——这是大值类型的长期行为。但这对 AnsiString 没有意义。也许编译器团队刚在 Delphi 2 中第一次实现长字符串时忘记更改语义。
| 归档时间: |
|
| 查看次数: |
4564 次 |
| 最近记录: |