(Delphi) 检查函数调用者环境中 switch 指令的状态

发布于 2024-08-01 16:36:00 字数 633 浏览 6 评论 0原文

我知道我可以使用此构造检查 Delphi 的 switch 指令的当前状态:

{$IFOPT R+}
      Writeln('Compiled with range-checking');
{$ENDIF}

由于我缺乏有关 Delphi 后端编译器如何工作的深入资料,我不确定是否有一种方法可以改变一个函数,取决于调用它的代码行中 switch 指令的状态。 它看起来像这样:

procedure P1;
begin  
    {$I+}
    P3; 
    {$I-}
end;

// ** state of I unknown

procedure P2;
begin
    {$I-}   
    P3; 
    {$I+}
end;

// ** state of I unknown

procedure P3;
begin       
    // Something like {$IFOPT I+}, but at the state P3 is called
    DoThis;
    {$ELSE}
    DoThat
    {$ENDIF}
end; 

我正在为遗留代码编写适配器,我迫切希望不受影响。 P3 不需要使用指令,但我认为这是正确的方法。

I know that I can check the current state of Delphi's switch directives using this construct:

{$IFOPT R+}
      Writeln('Compiled with range-checking');
{$ENDIF}

Since I'm lacking of in-depth sources on how the Delphi backend compiler works, I'm not sure wether there is a way of changing the behaviour of a function depending on the state of a switch directive at the code line calling it. It'll look something like this:

procedure P1;
begin  
    {$I+}
    P3; 
    {$I-}
end;

// ** state of I unknown

procedure P2;
begin
    {$I-}   
    P3; 
    {$I+}
end;

// ** state of I unknown

procedure P3;
begin       
    // Something like {$IFOPT I+}, but at the state P3 is called
    DoThis;
    {$ELSE}
    DoThat
    {$ENDIF}
end; 

I'm writing adapters for legacy code which I'd urgently like to be untouched.
P3 doesn't need to use directives, but I figured this to be the way to go.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧人 2024-08-08 16:36:00

不,没有简单的方法可以做到这一点。 编译器指令的操作级别与代码编译不同,它们不会将有关其状态的有意义的信息传递到代码中,并且它们当然不会在自己的范围之外应用。 如果要将数据传递给过程,唯一的方法是使用变量,可以是参数,也可以是全局变量。

No, there's no simple way to do that. Compiler directives operate on a different level than code compilation, and they don't pass meaningful information about their state into the code, and they certainly don't apply outside of their own scope. If you want to pass data to a procedure, the only way to do it is to use a variable, either an argument or a global.

懵少女 2024-08-08 16:36:00

像这样改变你的程序

procedure P1;
begin  
    {$I+}
    P3(true); 
    {$I-}
end;

procedure P2;
begin
    {$I-}       
    P3(false); 
    {$I+}
end;

// ** state of I unknown, but the parameter know the state

procedure P3(WIthRangeCheck: Boolean);
begin       
    if WIthRangeCheck then
       DoThis
    else
       DoThat;
end;

Change your Programm like this

procedure P1;
begin  
    {$I+}
    P3(true); 
    {$I-}
end;

procedure P2;
begin
    {$I-}       
    P3(false); 
    {$I+}
end;

// ** state of I unknown, but the parameter know the state

procedure P3(WIthRangeCheck: Boolean);
begin       
    if WIthRangeCheck then
       DoThis
    else
       DoThat;
end;
温柔戏命师 2024-08-08 16:36:00

据我所知,编译器指令仅适用于正在编译的代码,在本例中是“方法 P3 的调用”,而不是方法 P3 本身的代码。

如果您要在上面的代码中使用 $IFOPT I+,P3 将使用 $I+ 进行编译(因为上面设置了一点)并且 $IFOPT I+ 始终为 true。

As far as I know, compiler directives only work on the code being compiled, in this case 'the calling of method P3', not the code of method P3 itself.

If you were to use $IFOPT I+ in the code above, P3 would get compiled with $I+ (since set so a little above) and $IFOPT I+ is always true.

热情消退 2024-08-08 16:36:00

在 Delphi XE2 中,{$IFOPT I+} 的工作方式与您想要的完全一样:

procedure Test_IO_checkStatus(var isON: Boolean);
begin
{Ifopt I+}
  isON := true
  {$Else}
  isON := false;
  {Endif}
end;

当使用 {$I+} 编译项目时调用它,并且返回 TRUE; 使用 {$I-} 重新编译将返回 FALSE

In Delphi XE2, {$IFOPT I+} works exactly as you wanted:

procedure Test_IO_checkStatus(var isON: Boolean);
begin
{Ifopt I+}
  isON := true
  {$Else}
  isON := false;
  {Endif}
end;

Call it when the project was compiled with {$I+} and it returns TRUE; recompile with {$I-} it will return FALSE

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文