defined()

The defined() function, introduced in Elements 10, is a very special compiler function that is evaluated not at runtime but at compile time, and is used by the compiler to conditionally compile (or not compile) certain sections of code, depending on the presence of a Conditional Define. In that sense, it can replace more traditional {$IF ...} or #if ... directives, and allows for conditional code that flows more freely.

The method takes a single String parameter, and returns true at compile time if the given string is set as conditional define (either by the compiler, in project settings, or via an {$DEFINE ...}/#define ... directive), or false, if not.

Any code that would not execute due to a defined() check returning false – i.e. code that is in the if (or else) statement not being hit – will be completely eliminated by the compiler, at compile time. Note that this code is allowed to refer to identifiers that are unknown for the current compile target – essentially allowing you to use defined() to compile conditional code for different platforms or APIs.

Boolean short-circuit is applied, so defined() can be combined in an if statement with other, runtime-evaluated conditions.

Simple example:

if defined("COCOA") then
  writeLn('this code was compiled for Cocoa.')
else
  writeLn('this code was compiled for .NET, Java or Island.');
if (defined("COCOA"))
  writeLn("this code was compiled for Cocoa.");
else
  writeLn("this code was compiled for .NET, Java or Island.");
if #defined(COCOA) {
  writeLn("this code was compiled for Cocoa.")
} else {
  writeLn("this code was compiled for .NET, Java or Island.")
}
if (defined("COCOA"))
  writeLn("this code was compiled for Cocoa.");
else
  writeLn("this code was compiled for .NET, Java or Island.");

In the above example, the compiler would emit the first writeL() call only when compiling for Cocoa, and the second one only when compiling for a different platform.

But defined() can do more:

if defined("MACOS") or (Environment.OS ≠ OperatingSystem.Windows) then
  directorySeparator := '/'
else
  directorySeparator := System.IO.Path.DirectorySeparator;
if (defined("MACOS") || Environment.OS != OperatingSystem.Windows)
  directorySeparator = "/";
else
  directorySeparator = System.IO.Path.DirectorySeparator;
if #defined(MACOS) || Environment.OS != OperatingSystem.Windows { 
  directorySeparator = "/"
} else {
  directorySeparator = System.IO.Path.DirectorySeparator
}
if (defined("MACOS") || Environment.OS != OperatingSystem.Windows)
  directorySeparator = "/";
else
  directorySeparator = System.IO.Path.DirectorySeparator;

In this example, two advanced features of defined() can be seen:

For one, defined() is combined with a regular run-time condition in the same if clause. The compiler will evaluate defined("MACOS") at compile time. If true, it will short-circuit the rest of the expression (i.e. completely ignore it and not even emit code for it), and go straight to emitting the simple assignment statement. Only if false will it generate code for the second check of Environment.OS, and emit both parts of the if clause.

For another, note how the else statement of the if clause makes reference to the System.IO.Path class of the .NET framework. This class does not even exist when compiling for Cocoa – yet the code shown above will compile fine for Cocoa and .NET alike, because the else clause will be eliminated for Cocoa.

Using defined() outside of if

Note that while defined() can be called as a function in ay context, it will only directly influence compiler behavior when used inside the expression of an if statement. The following code will work, but the isCocoa variable will be a regular boolean (its initial value determined at compile time, and the if check will be executed at runtime):

var isCocoa := defined("COCOA");
if isCocoa then
  writeLn('this is Cocoa.')
else
  writeLn('this is .NET, Java or Island.');
bool isCocoa = defined("COCOA");
if (isCocoa))
  writeLn("this is Cocoa.");
else
  writeLn("this is .NET, Java or Island.");
let cocoa = defined("COCOA")
if isCocoa {
  writeLn("this is Cocoa.")
} else {
  writeLn("this is .NET, Java or Island.")
}
boolean cocoa = defined("COCOA");
if (isCocoa)
  writeLn("this is Cocoa.");
else
  writeLn("this is .NET, Java or Island.");

Swift

Symmetrically to available() and #available, a special syntax for defined() is provided for the Swift language. #defined() can be used with a hash symbol, and omitting the quotes around the name of the define.

See Also