5

In Delphi, you can define symbols, just like in C/C++.

Delphi:

{$DEFINE MY_SYMBOL}

C/C++:

#define MY_SYMBOL

This allows you to check whether the symbol is defined by using {$IFDEF MY_SYMBOL} in Delphi, or #ifdef MY_SYMBOL in C/C++.

This is a boolean value - either the symbol is defined during pre-processing or not. However, C/C++ also allows you to assign values to preprocessor symbols. E.g.:

#ifdef DEBUG
#define DB_HOST "127.0.0.1"
#else
#define DB_HOST "123.456.789.123"
#endif

Database *pDatabase = new Database(DB_HOST);

Is assigning a value to a preprocessor symbol possible in Delphi, or does Delphi only allow you to determine whether or not a symbol has been defined at all?

EDIT: As Delphi doesn't support symbol values in the preprocessor, I'm assuming it doesn't support preprocessor macros. Am I right in this assumption?

For example, in C you can define a preprocessor macro that gets copied and pasted with the appropriate parameters before compilation. This is useful when you want "inline function" capability for fast operations (e.g., binary logic, testing in an integer values, bit-shifting, etc) without the overhead of stack frames, parameter passing and the like.

#define OK_FLAG 0x00000001
#define OK(f) (f & OK_FLAG)

#define WEAK_XOR_CIPHER(v) (v ^ 0xff)
magnus
  • 4,031
  • 7
  • 26
  • 48
  • 1
    Delphi have no preprocessor, to start with. Preprocessor is a tool specific to C and C++. Preprocessor macro is a macro substitution **literally**. – Free Consulting Mar 12 '14 at 05:23
  • @Free, but it seems you may use an [`external one`](http://sourceforge.net/projects/dpp32/) (no experience with it though). – TLama Mar 12 '14 at 08:40

1 Answers1

9

You can simply use a constant, and define the value:

const
{$IFDEF DEBUG}
  DB_Host = '127.0.0.1';
{$ELSE}
  DB_Host = '123.45.67.89';
{$ENDIF}

You can also do the reverse (test for something not being defined):

const
{$IFNDEF DEBUG}
  DB_Host = '123.45.67.89';
{$ELSE}
  DB_Host = '127.0.0.1';
{$ENDIF}

This ensures that DB_Host is always available, and has the appropriate value when not debugging.

Recent versions of Delphi allow you to test the value of constants. For instance, the System unit has the constant RTLVersion defined, and you can test for a value using it:

{$IF RTLVersion <= 26}
  // Less than XE5
{$ELSE}
  // XE5
{$IFEND}

Delphi doesn't support macros of any sort, however. The typical solution to not having macros is to use an inline function. See, for instance the Windows unit's implementation of the WinAPI RGB macro:

function RGB(r, g, b: Byte): COLORREF; inline;

function RGB(r, g, b: Byte): COLORREF;
begin
  Result := (r or (g shl 8) or (b shl 16));
end;
AlainD
  • 5,413
  • 6
  • 45
  • 99
Ken White
  • 123,280
  • 14
  • 225
  • 444
  • I don't like the reverse, simply because `if not condition then bar else foo` is harder to read than `if condition then foo else bar`. – Mason Wheeler Mar 12 '14 at 01:03
  • @Mason: It's how we use it where I work, so we're used to it. Personal preference, I guess, like code formatting. Editing to better make the point I intended, though. Thanks. – Ken White Mar 12 '14 at 01:06
  • The Delphi precompiler does not support macros at all, and precompiler symbols can only be used in `$IF` and `$IF(N)DEF` statements. – Remy Lebeau Mar 12 '14 at 01:13
  • 1
    Kind of odd that you use <= for a less than test. Using <27 would be clearer. – David Heffernan Mar 12 '14 at 07:26
  • 2
    FWIW, one thing that may come in handy with the mobile compilers: `{$IF not declared(AnsiString)}` etc. – Rudy Velthuis Mar 12 '14 at 08:22