C和Delphi中的条件编译

时间:2012-01-20 06:45:22

标签: c delphi conditional-compilation ifndef

下一个模式在C代码中很常见:

#ifndef SOMETHING
#define SOMETHING
#endif

在Delphi代码中也可以使用该模式:

{$IFNDEF SOMETHING}
{$DEFINE SOMETHING}
{$ENDIF}

但这并不常见 - 我从来没有见过它。如果Delphi代码需要条件定义,它只是在没有IFNDEF检查的情况下定义它。

为什么这样? C和Delphi之间的条件编译有什么区别,以便前者需要ifndef检查而后者不需要检查?

2 个答案:

答案 0 :(得分:12)

这是因为这不仅是常见的,而且在C中是强制性的:

#include <something.h>

虽然这在Delphi中很少使用。使用时,它实际上用于设置{$DEFINE}的:{/ p>

{$INCLUDE 'something.inc'}

这很重要,因为DEFINES仅在编译一个对象时有效(可能是.PAS文件或.C文件。 Delphi使用uses子句包含其他单元,而C使用include包含它的头部。 C标头中可能包含其他标头。您询问的模式用于防止递归地重新包含相同的标题。

为了使maters清晰,这里有一个可能在C中使用的样本,以及Delphi中的等价物。假设我们设置了3个文件,其中A需要同时包含BC,而B只需要包含C。 “C”文件如下所示:

// ----------------------- A.h
#ifndef A
#define A

#include "B.h"
#include "C.h"

// Stuff that goes in A

#endif

// ------------------------ B.h
#ifndef B
#define B

#include "C.h"

// Stuff that goes in B

#endif

// ----------------------- C.h
#ifndef C
#define C

// Stuff that goes in C

#endif

如果没有C.h中的条件定义,C.h文件最终会在A.h中被包含两次。这就是代码在Delphi中的样子:

// --------------------- A.pas
unit A;

interface

uses B, C;

implementation

end.

// --------------------- B.pas
unit B

interface

uses C;

implementation

end.

// --------------------- C.pas

unit C

interface

implementation

end.

Delphi / Pascal版本不需要保护“C”不被包含在“A”中两次,因为它不使用{$INCLUDE}来实现此目标,它使用uses声明。编译器将从B.dcu文件和C.dcu文件中获取导出的符号,而不存在两次包含C.dcu符号的风险。


在C代码中看到更多预编译器指令的其他原因:

  • 预编译器比Delphi强大得多。 Delphi代码中的{$DEFINE}仅处理条件编译,而C变体既可用于条件编译,也可用作单词替换的形式。
  • 强制使用#include标头意味着您可以拥有定义宏的标头。或者,您可以通过在实际#define
  • 之前指定一些#include <header.h>语句来配置标头

答案 1 :(得分:3)

此模式不是“C语言代码”(.c或.cpp源文件)。它在C / C ++ 标题(.h)文件中很常见:

#ifndef SOMETHING
#define SOMETHING
#endif

原因是防止SAME标题在同一翻译单元中无意中包含多个时间。

例如,假设模块“a.c”使用标题“b.h”。并且“b.h”#include的“c.h”。这意味着“a.c”明确使用“b”,并且隐式地也使用“c”。到目前为止,非常好。

现在让我们说“c.h”使用“b.h”。 “#ifndef / #define / #endif”的东西防止“b”被#包括在第二次(一次在“a”中被“a”,第二次在“a”中来自“c”)。 / p>

这在Delphi中是不必要的。 Delphi“$ ifdef”仅用于条件编译; Delphi“单元”负责处理潜在的递归和/或循环依赖。