我知道以下函数语句的答案:
if (TestFunc1()) and (TestFunc2()) then
DoSomething();
这个问题很好地解答了: Delphi 'AND' evaluation with 2 conditions
比如说,你可以通过调试或记录来轻松测试。但是你如何测试编译器在这个例子中做了什么(比如说ech参数定义为布尔值):
if (SomeObj1.bNaughtyGlobal1) and (SomeObj2.bNaughtyGlobal2) then
DoSomething();
是的,我知道参数最好隐藏在访问器函数后面......但是有没有一种聪明的方法来测试是否正在访问SomeObj2?
答案 0 :(得分:4)
答案与您链接的问题相同。作为and
的操作数的表达式是函数调用还是变量,这并不重要。如果符合以下条件,将评估第二个操作数:
默认编译器选项启用了短路评估,并且我不知道任何改变它的情况。因此,假设您在启用短路评估的情况下进行编译,那么当且仅当第一个操作数的计算结果为真时,才会计算第二个操作数。
如果您希望在调试器下看到这个,请尝试使用和不使用短路评估的程序:
{$APPTYPE CONSOLE}
type
TMyRecord = record
foo: Integer;
end;
PMyRecord = ^TMyRecord;
var
P: PMyRecord = nil;
begin
if Assigned(P) and (P.foo=1) then
Writeln;
end.
没有短路,P.foo
的评估是运行时错误。通过短路评估,没有运行时错误。
确实,这个具体的例子是应该启用短路评估的最佳原因之一。否则这样的代码会过于冗长。
答案 1 :(得分:3)
在
上设置断点if (SomeObj1.bNaughtyGlobal1) and (SomeObj2.bNaughtyGlobal2) then
现在将程序运行到断点。 打开CPU窗口(view-> Debug Windows-> CPU)并逐步执行处理器指令。 在那里你会看到跳转指令,你也会看到,如果SomeObj1.bNaughtyGlobal1为false,则不会评估任何其他内容,而不是你的SomeObj2对象。
答案 2 :(得分:1)
设置SomeObj1.bNaughtyGlobal1 := False
和SomeObj2 := nil
。如果编译器行为不端并评估and
表达式的两边,那么当程序尝试从空引用读取bNaughtyGlobal2
值时,您将获得访问冲突。