[fpc-pascal] Hack for C-like macro functions — will it work in future?

Tomas Hajny XHajT03 at hajny.biz
Wed Sep 24 10:15:19 CEST 2014


On Wed, September 24, 2014 02:59, Роман wrote:
 .
 .
> {$macro on}
> {$ifdef DEBUG}
>      {$define Log := ActualLog}
> {$else}
>      {$define Log := ;//}
> {$endif}
>
> if A then
>    Log('will work until followed by ELSE at all or any statements on the
> same line (because of ; and //, respectively).');
> if B then
>    Log('And should not be carried over to the next line, of course!');
>
> Because constant {$ifdef DEBUG} ActualLog(...); {$endif} are rather
> cumbersome.
>
> This is by design? Can I rely on this behavior in the future? ._.

I assume that this should keep working in the future as well.

However, the trunk compiler offers also another option, although it may or
may not be usable for you. In particular, take the following:

---------
var
 S2: string;

procedure Log (S: string);
begin
 {$IFDEF TEST}
  WriteLn (S);
 {$ENDIF TEST}
end;

begin
 ReadLn (S2);
 Log ('Input = ' + S2);
end.
=========

If this is compiled with trunk compiler using -OoREMOVEEMPTYPROCS (without
-dTEST), procedure Log is not called at all and the concatenation of
strings in its parameter is skipped as well.

As you can see, this solution shares the benefit of your macro approach,
i.e. it doesn't suffer from IFDEF pollution either. At the same time, it
is much safer and supports also more complex scenarios (multi-line strings
and no restrictions on where Log may be called in the program flow).

There are two caveats (at least with the version I tried - about 2 months
old):

1) The call isn't removed if the (conditionally) empty procedure is
declared in another unit _unless_ you use -O4 (which includes also some
other optimizations which may not be safe for your use). There might be
another -Oo... option which allows to use this without enabling all
uncertain optimizations, but I don't know whether such an option exists
and which one it would be.

2) Interestingly, there is still some code generated for the empty
procedure (and also included in the final executable). The size of this
code is negligible, but it's there.

Tomas





More information about the fpc-pascal mailing list