跳到主要内容

Conditional compilation

#if, #ifdef, #ifndef, #elif, #else and #endif select which regions of a file the compiler sees.

#ifdef __PACKAGE_SOCKETS__
int open_port() { return socket_create(STREAM, "cb"); }
#else
int open_port() { return -1; }
#endif

#ifdef / #ifndef

Test only whether a macro is defined (user #defines and driver predefines both count):

#ifndef MUDLIB_H
#define MUDLIB_H
...
#endif // classic include guard

#if expressions

#if and #elif evaluate an integer constant expression. Macros in the expression are expanded first; the expression is then evaluated over tokens with full C operator precedence — parentheses, unary ! ~ -, arithmetic * / % + -, shifts, comparisons, bitwise & ^ |, and logical && ||:

#define X 1+1
#if X*2 == 3 // expands to 1+1*2 -- true, as in C
#endif

Two extra operators are available:

  • defined(NAME) (or defined NAME) — 1 if NAME is a defined macro.
  • efun_defined(name) — 1 if the driver was built with the named efun.
#if defined(__PACKAGE_CRYPTO__) && efun_defined(hash)
string h = hash("sha256", data);
#endif

An undefined identifier appearing in an #if expression evaluates to 0, as in C. A missing expression is a compile error.

Nesting and skipped regions

Conditionals nest arbitrarily. Inside a false branch the compiler still tracks #if/#endif nesting (so a skipped region may contain its own conditionals), but nothing else in the region is evaluated — including other directives. An unmatched #elif/#else/#endif is a compile error.