Conditional Compilation in C and Delphi

The following code is common in C code:

#ifndef SOMETHING #define SOMETHING #endif 

The template is also possible in Delphi code:

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

but this is not common - I never saw him at all. If Delphi code requires a conditional definition, it simply defines it without checking IFNDEF .

Why is that? What is the difference in conditional compilation between C and Delphi, so the IFNDEF check IFNDEF needed for the former and not needed for the latter?

+4
source share
2 answers

This is because it is not only regular, but also mandatory in C:

 #include <something.h> 

Although it is rarely used in Delphi. And when it is used, it really used to configure these {$DEFINE} :

 {$INCLUDE 'something.inc'} 

This matters because DEFINES are only valid when compiling a single object (it can be a .PAS file or a .C file). Delphi uses the uses to include other units, and C uses include to include headers. In C headers may include other headers. The pattern you are asking for is used to prevent recursive re-inclusion of the same header.

To make the matrices crystal clear, here is an example of what can be used in C, and the equivalent in Delphi. Let's say we have 3 files setup, where A must include both B and C , and B needs to include C C files look like this:

 // ----------------------- Ah #ifndef A #define A #include "Bh" #include "Ch" // Stuff that goes in A #endif // ------------------------ Bh #ifndef B #define B #include "Ch" // Stuff that goes in B #endif // ----------------------- Ch #ifndef C #define C // Stuff that goes in C #endif 

Without defining the conditions in Ch file Ch will eventually be included twice in Ah . So the code in Delphi will look:

 // --------------------- 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. 

The Delphi / Pascal version should not protect "C" from being included twice in "A", because it does not use {$INCLUDE} to achieve this, it uses the uses statement. The compiler will get exported characters from the B.dcu and C.dcu without the risk of including characters from C.dcu twice.


Other reasons to see more precompiler commands in C code:

  • The precompiler is much more powerful than Delphi. A {$DEFINE} in Delphi code deals only with conditional compilation, and variant C can be used both for conditional compilation and as a replacement for words.
  • Mandatory use of #include for headers means that you can have a header that defines macros. Or you may have a header configured by specifying some #define before the actual #include <header.h>
+12
source

This pattern is NOT "common in C" (.c or .cpp source files). It is common in C / C ++ header files (.h):

 #ifndef SOMETHING #define SOMETHING #endif 

The reason is to prevent the SAME header from being unintentionally, including MULTIPLE TIMES in the same translation unit.

For example, let the module "ac" use the header "bh". And "bh" # include "ch". This means that โ€œacโ€ explicitly uses โ€œbโ€ and implicitly also uses โ€œcโ€. So far so good.

Now let's say that "ch" uses "bh". "# Ifndef / # define / # endif" stuff PREVENTS "b" from # SECOND TIME include (once in "a" to "a", second time in "a" from "c").

This is all superfluous in Delphi. Delphi "$ ifdef" is used only to compile conditions; Delphi "units" take care of potentially recursive and / or circular dependencies.

+3
source

Source: https://habr.com/ru/post/1391983/


All Articles