(Delphi) Check state of a switch directive in the function caller's environment
-
16-09-2019 - |
Question
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.
Solution
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;
OTHER TIPS
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.
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.
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