C和Delphi中的条件编译

klu*_*udg 4 c delphi conditional-compilation ifndef

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

#ifndef SOMETHING
#define SOMETHING
#endif
Run Code Online (Sandbox Code Playgroud)

这种模式在Delphi代码中也是可能的:

{$IFNDEF SOMETHING}
{$DEFINE SOMETHING}
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)

但这并不常见 - 我从来没有见过它.如果Delphi代码需要条件定义,它只是定义它而不IFNDEF检查.

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

Cos*_*und 12

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

#include <something.h>
Run Code Online (Sandbox Code Playgroud)

虽然这在Delphi中很少使用.当使用它时,它实际上用于设置它们{$DEFINE}:

{$INCLUDE 'something.inc'}
Run Code Online (Sandbox Code Playgroud)

这很重要,因为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
Run Code Online (Sandbox Code Playgroud)

如果没有条件定义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.
Run Code Online (Sandbox Code Playgroud)

Delphi/Pascal版本不需要保护"C"不被包含在"A"中两次,因为它不使用它{$INCLUDE}来实现这个目标,它使用该uses语句.编译器将从B.dcu文件和C.dcu文件中获取导出的符号,而不会有C.dcu两次包含符号的风险.


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

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