Delphi的条件编译允许定义符号包含值吗?

5
在Delphi中,你可以定义符号,就像在C/C++中一样。
{$DEFINE MY_SYMBOL}

C/C++:

#define MY_SYMBOL

这可以让你使用Delphi中的{$IFDEF MY_SYMBOL},或者C/C++中的#ifdef MY_SYMBOL来检查符号是否被定义。
这是一个布尔值——无论预处理期间符号是否被定义。但是,C/C++还允许您为预处理器符号分配值。例如:
#ifdef DEBUG
#define DB_HOST "127.0.0.1"
#else
#define DB_HOST "123.456.789.123"
#endif

Database *pDatabase = new Database(DB_HOST);

在Delphi中,是否可以给预处理器符号赋值,还是只允许确定符号是否已定义?编辑:由于Delphi不支持预处理器中的符号值,我假设它不支持预处理器宏。这个假设正确吗?例如,在C语言中,您可以定义一个预处理器宏,在编译之前将其复制并粘贴到适当的参数中。这在您想要快速操作(例如二进制逻辑、整数值测试、位移等)的“内联函数”功能时非常有用,而不需要堆栈帧、参数传递等开销。
#define OK_FLAG 0x00000001
#define OK(f) (f & OK_FLAG)

#define WEAK_XOR_CIPHER(v) (v ^ 0xff)

1
Delphi没有预处理器,这是一个特定于C和C ++的工具。预处理器宏是一种字面上的宏替换。 - Free Consulting
@Free,但似乎您可以使用一个外部的(虽然我没有使用过). - TLama
1个回答

9
您可以简单地使用一个常量并定义该值:
const
{$IFDEF DEBUG}
  DB_Host = '127.0.0.1';
{$ELSE}
  DB_Host = '123.45.67.89';
{$ENDIF}

您也可以进行相反的操作(测试某物未被定义):
const
{$IFNDEF DEBUG}
  DB_Host = '123.45.67.89';
{$ELSE}
  DB_Host = '127.0.0.1';
{$ENDIF}

这样做可以确保 DB_Host 始终可用,并且在不进行调试时具有适当的值。
近期的 Delphi 版本允许您测试常量的值。例如,System 单元定义了常量 RTLVersion,您可以使用它来测试一个值:
{$IF RTLVersion <= 26}
  // Less than XE5
{$ELSE}
  // XE5
{$IFEND}

Delphi不支持任何类型的宏,然而,没有宏的典型解决方案是使用内联函数。例如,请参考Windows单元中实现WinAPI RGB宏的方式:

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;

我不喜欢反向写法,因为if not condition then bar else fooif condition then foo else bar更难读。 - Mason Wheeler
@Mason:这是我们工作中的使用方式,所以我们已经习惯了。我猜这是个人偏好,就像代码格式化一样。不过我会编辑一下以更好地表达我的意思。谢谢。 - Ken White
Delphi预编译器完全不支持宏,预编译符号只能在$IF$IF(N)DEF语句中使用。 - Remy Lebeau
1
使用“<=”进行小于测试有点奇怪。使用“<27”会更清晰明了。 - David Heffernan
2
顺便说一句,对于移动编译器可能会有用的一件事情是:{$IF not declared(AnsiString)}等。 - Rudy Velthuis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接