From fdf86a65cf99f157ae582d03581da7ba25c26138 Mon Sep 17 00:00:00 2001
From: Mactavish <maczhanchao@yahoo.com>
Date: Mon, 24 Apr 2023 11:52:56 +0200
Subject: [PATCH] finish preprocessor

---
 clang.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/clang.md b/clang.md
index 2e9931e..56d2dbe 100644
--- a/clang.md
+++ b/clang.md
@@ -472,7 +472,7 @@ A full compilation in C is depicted in the following figure:
 
 A detailed explanation can be found [here](https://www.scaler.com/topics/c/compilation-process-in-c/).
 
-## C Macros
+## C Preprocessor
 
 You often see C preprocessor macros defined to create "small functions"
 
@@ -491,3 +491,71 @@ Example:
 // int y = 2;
 // int z = twox(y++); => z = (y++ + y++);  the value of z actaully depends on the order of evaluation
 ```
+
+You can also use `#define` to define some constants:
+
+```c
+#define ARR_SIZE 100
+```
+
+### Conditional Inclusion
+
+Frequently, you’ll need to write different code to support different implementations. You can use the preprocessing directives `#if`, `#elif`, `#else` to conditionally include source code.
+
+Here is a simple example of using conditional inclusion:
+
+```c
+#include <stdio.h>
+
+int main() {
+#ifdef __linux__
+    printf("I am the Happy Penguin!\n");
+#elif _WIN32
+    printf("Welcome to MS Windows ( I rule!).\n");
+#elif __APPLE__&&__MACH__
+    printf("Welcome to I am cool!\n");
+#else
+    printf("Uh! who am i?\n");
+#endif
+}
+```
+
+Note that the above `#ifdef` strings are standard ways of detecting the Operating System the code is being compiled on. See https://sourceforge.net/p/predef/wiki/OperatingSystems/ for further details.
+
+### Header Guards
+
+One problem you will face when writing header files is preventing programmers from including the same file twice in a translation unit.
+
+Given that you can transitively include header files, you could easily include the same header file multiple times by accident.
+
+Header guards ensure that a header file is included only once per translation unit.
+
+Suppose we have a `bar.h` file:
+
+```c
+#ifndef BAR_H
+#define BAR_H
+
+int func(void) { return 1; }
+
+#endif /* BAR_H */
+```
+
+And a `foo.c` file:
+
+```c
+foo.c
+
+#include "bar.h"
+#include "bar.h" // Repeated inclusion is // usually not this obvious.
+
+int main(void) {
+    return func();
+}
+```
+
+Using the header guard prevents the function definition of `func` being included twice.
+
+A common practice when picking the identifier to use as a header file guard is to use the salient parts of the file path, filename, and extension, separated by an underscore and written in all capital letters. E.g. `FOO_BAR_BAZ_H` for a file located in `foo/bar/baz.h`.
+
+There are other ways of using the preprocessor directives and macros, this [article](https://en.wikibooks.org/wiki/C_Programming/Preprocessor_directives_and_macros) and [GCC documentation](https://gcc.gnu.org/onlinedocs/cpp/) provide extensive information about them.
-- 
GitLab