views:

246

answers:

3

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.

+4  A: 

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.

Mason Wheeler
A: 

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.

Stijn Sanders
+1  A: 

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;
Heinz Z.
I figured that already, but that's exactly what I want to avoid :-/
kaeff
@kaeff Perhaps if you tell why you want to avoid this kind of solution then you can get an other one. If you can change the body of P3 but not parameterlist then use a variable. Or when you can't assure that all caller cooperate, you can provoked a range violation and check if an exception is thrown.
Heinz Z.