9.5 Flow Control in Macros

The following macro directives are supplied:

  • -undef(Macro).
  • Causes the macro to behave as if it had never been defined.
  • -ifdef(Macro).
  • Evaluate the following lines only if Macro is defined.
  • -ifndef(Macro).
  • Evaluate the following lines only if Macro is not defined.
  • -else.
  • Only allowed after an ifdef or ifndef directive. If that condition is false, the lines following else are evaluated instead.
  • -endif.
  • Specifies the end of an ifdef, an ifndef directive, or the end of an if or elif directive.
  • -if(Condition).
  • Evaluates the following lines only if Condition evaluates to true.
  • -elif(Condition).
  • Only allowed after an if or another elif directive. If the preceding if or elif directives do not evaluate to true, and the Condition evaluates to true, the lines following the elif are evaluated instead.

Note

The macro directives cannot be used inside functions.

Example:

  1. -module(m).
  2. ...
  3.  
  4. -ifdef(debug).
  5. -define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])).
  6. -else.
  7. -define(LOG(X), true).
  8. -endif.
  9.  
  10. ...

When trace output is desired, debug is to be defined when the module m is compiled:

  1. % erlc -Ddebug m.erl
  2.  
  3. or
  4.  
  5. 1> c(m, {d, debug}).
  6. {ok,m}

?LOG(Arg) is then expanded to a call to io:format/2 and provide the user with some simple trace output.

Example:

  1. -module(m)
  2. ...
  3. -ifdef(OTP_RELEASE).
  4. %% OTP 21 or higher
  5. -if(?OTP_RELEASE >= 22).
  6. %% Code that will work in OTP 22 or higher
  7. -elif(?OTP_RELEASE >= 21).
  8. %% Code that will work in OTP 21 or higher
  9. -endif.
  10. -else.
  11. %% OTP 20 or lower.
  12. -endif.
  13. ...

The code uses the OTP_RELEASE macro to conditionally select code depending on release.