下一个模式在C代码中很常见:
#ifndef SOMETHING
#define SOMETHING
#endif
在Delphi代码中也可以使用该模式:
{$IFNDEF SOMETHING}
{$DEFINE SOMETHING}
{$ENDIF}
但这并不常见 - 我从来没有见过它。如果Delphi代码需要条件定义,它只是在没有IFNDEF
检查的情况下定义它。
为什么这样? C和Delphi之间的条件编译有什么区别,以便前者需要ifndef
检查而后者不需要检查?
答案 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
需要同时包含B
和C
,而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代码中看到更多预编译器指令的其他原因:
{$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“单元”负责处理潜在的递归和/或循环依赖。