C 和 Delphi 中的条件编译
下一个模式在 C 代码中很常见:
#ifndef SOMETHING
#define SOMETHING
#endif
该模式在 Delphi 代码中也是可能的:
{$IFNDEF SOMETHING}
{$DEFINE SOMETHING}
{$ENDIF}
但它并不常见 - 我从来没有见过它。如果 Delphi 代码需要条件定义,它只是定义它而不进行 IFNDEF
检查。
为什么会这样呢? C和Delphi的条件编译有什么区别,前者需要ifndef检查而后者不需要?
The next pattern is common in C code:
#ifndef SOMETHING
#define SOMETHING
#endif
The pattern is possible in Delphi code too:
{$IFNDEF SOMETHING}
{$DEFINE SOMETHING}
{$ENDIF}
but it is not common - I have never seen it at all. If a Delphi code requires a conditional define, it just defines it without IFNDEF
check.
Why so? What is the difference in conditional compilation between C and Delphi so that ifndef
check is needed for former and not needed for latter?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是因为这在 C 中不仅常见而且是强制的:
而在 Delphi 中很少使用。使用时,它实际上用于设置那些
{$DEFINE}
:这很重要,因为 DEFINES 仅在编译一个对象时有效(可能是
.PAS
文件或.C
文件)。 Delphi 使用uses
子句来包含其他单元,而 C 使用include
来包含其标头。在 C 标头中,标头本身可能包含其他标头。您所询问的模式用于防止递归地重新包含相同的标头。为了让事情变得一目了然,这里有一个可以在 C 中使用的示例,以及 Delphi 中的等效示例。假设我们有 3 个文件设置,其中
A
需要同时包含B
和C
,以及B
> 只需要包含C
。 “C”文件将如下所示:如果没有
Ch
中的条件定义,Ch
文件最终将被包含在Ah
中两次。这就是代码在 Delphi 中的样子:Delphi/Pascal 版本不需要保护“C”不被包含在“A”中两次,因为它不使用
{$INCLUDE}
为了实现这个目标,它使用uses
语句。编译器将从B.dcu
文件和C.dcu
文件获取导出的符号,而不存在包含来自C.dcu
的符号的风险两次。在 C 代码中看到更多预编译器指令的其他原因:
{$DEFINE}
仅处理条件编译,而 C 变体既可用于条件编译,也可作为单词替换的一种形式。#include
意味着您可以拥有定义宏的标头。或者,您可以通过在实际的#include
之前指定一些#define
语句来配置标头That's because this is not only common but mandatory in C:
While this is rarely used in Delphi. And when used, it's actually used to set up those
{$DEFINE}
's:This matters because DEFINES are only valid while compiling one object (may it be a
.PAS
file or a.C
file). Delphi uses theuses
clause to include other units, while C uses theinclude
to include it's headers. InC
headers might themselves include other headers. The pattern you're asking about is used to prevent recursively re-including the same header.To make maters crystal-clear, here's a sample of what one might use in C, and the equivalent in Delphi. Let's say we've got a 3 files setup, where
A
needs to include bothB
andC
, andB
only needs to includeC
. The "C" files would look like this:Without the conditional defines in
C.h
, theC.h
file would end up being included twice inA.h
. This is how the code would look like in Delphi:The Delphi/Pascal version doesn't need to protect "C" from being included twice in "A" because it doesn't use the
{$INCLUDE}
to achieve this goal, it use theuses
statement. The compiler would get the exported symbols from theB.dcu
file and theC.dcu
files with no risk of including symbols fromC.dcu
twice.Other reasons to see a lot more precompiler directives in C code:
{$DEFINE}
in Delphi code only deals with conditional compilation, while the C variant can be used for both conditional compilation and as a form of word substitution.#include
for headers means you can have a header that defines macros. Or you can have a header that's configured by specifying some#define
statements before the actual#include <header.h>
此模式在“C”代码(.c 或 .cpp 源文件)中并不常见。它在 C/C++ 标头 (.h) 文件中很常见:
原因是为了防止同一标头无意中在同一翻译单元中包含多次。
例如,假设模块“ac”使用标头“bh”。和“bh”#include 的“ch”。这意味着“ac”显式使用“b”,并且隐式也使用“c”。到目前为止,一切都很好。
现在假设“ch”使用“bh”。 “#ifndef/#define/#endif”内容可以防止“b”第二次被#include(一次是“a”在“a”中,第二次是“c”在“a”中)。
这在Delphi 中都是不必要的。 Delphi“$ifdef”仅用于条件编译; Delphi“单元”负责潜在的递归和/或循环依赖。
This pattern is NOT "common in C" code (.c or .cpp source files). It's common in C/C++ headers (.h) files:
The reason is to prevent the SAME header from being inadvertantly including MULTIPLE TIMES in the same translation unit.
For example, let's say module "a.c" uses header "b.h". And "b.h" #include's "c.h". That means "a.c" explicitly uses "b", and implicitly also uses "c". So far, so good.
Now let's say that "c.h" uses "b.h". The "#ifndef/#define/#endif" stuff PREVENTS "b" from being #include'd a SECOND TIME (once in "a" by "a", the second time in "a" from "c").
This is all unnecessary in Delphi. Delphi "$ifdef" is used only for condition compilation; Delphi "units" take care of potentially recursive and/or circular dependencies.