{"id":23280,"date":"2025-02-18T21:09:56","date_gmt":"2025-02-18T21:09:56","guid":{"rendered":"https:\/\/wolles-elektronikkiste.de\/?p=23280"},"modified":"2025-09-10T18:54:59","modified_gmt":"2025-09-10T18:54:59","slug":"preprocessor-directives","status":"publish","type":"post","link":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives","title":{"rendered":"Preprocessor directives"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">About this Post<\/h2>\n\n<p>You have all used preprocessor directives such as <code>#define<\/code> or <code>#include<\/code>. However, the less experienced may not really know the difference between preprocessor directives and the actual program code. This article aims to explain this difference, which preprocessor directives are available, how to use them and what alternatives there are. And perhaps there will be some aspects that will also be of interest to the &#8220;older hands&#8221;. I will cover the following:    <\/p>\n\n<ul>\n<li><a href=\"#what_it_is\">What is the preprocessor, what are preprocessor directives?<\/a><\/li>\n<li><a href=\"#include\">Including files &#8211; #include<\/a><\/li>\n<li><a href=\"#define\">Macros &#8211; #define<\/a>\n<ul>\n<li><a href=\"#macros_w_o_vars\">Simple macros without passing variables<\/a>\n<ul>\n<li><a href=\"#stumbling_blocks\">Pitfalls with simple macros<\/a><\/li>\n<li><a href=\"#alternatives_to_define\">Alternatives to #define (const\/constexpr, enum)<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#macros_w_vars\">Macros with passing variables<\/a>\n<ul>\n<li><a href=\"#macros_vs_functions\">macros vs. functions<\/a><\/li>\n<li><a href=\"#arduino_macros\">&#8220;Arduino macros&#8221;<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#predef_macros\">Predefined macros<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#conditional_inclusion\">Conditional inclusion of code &#8211; #ifdef, #ifndef &amp; Co<\/a>\n<ul>\n<li><a href=\"#example_double_incl\">Application example 1: Avoiding double reading of files<\/a><\/li>\n<li><a href=\"#example_debugging\">Application example 2: Debugging<\/a><\/li>\n<li><a href=\"#example_mcu_specific_code\">Application example 3: MCU-specific code<\/a>\n<ul>\n<li><a href=\"#find_defines\">Where can I find the board or MCU #defines?<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#warnings_errors\">Warnings and errors &#8211; #warning, #error<\/a><\/li>\n<li><a href=\"#line\">Manipulating the line counter and file name &#8211; #line<\/a><\/li>\n<li><a href=\"#pragma\">The multifunctional tool &#8211; #pragma<\/a>\n<ul>\n<li><a href=\"#pragma_once\">#pragma once<\/a><\/li>\n<li><a href=\"#pragma_poison\">#pragma poison<\/a><\/li>\n<li><a href=\"#pragma_msg_warn_err\">#pragma message \/ warning \/ error<\/a><\/li>\n<li><a href=\"#pragma_diagnostic\">#pragma diagnostic<\/a><\/li>\n<li><a href=\"#pragma_pack\">#pragma pack()<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n<h2 class=\"wp-block-heading\" id=\"what_it_is\">What is the preprocessor, what are preprocessor directives?<\/h2>\n\n<p>The preprocessor is a program or component that is used before the actual compilation or execution of a code. It is often used in programming languages such as C and C++ (including Arduino code) to process source code before compilation. Essentially, the preprocessor performs the following tasks:  <\/p>\n<ul>\n<li>Replacement of strings by macros.<\/li>\n<li>Inclusion of files.<\/li>\n<li>Conditional inclusion or exclusion of code.<\/li>\n<li>Control of compiler behavior (messages, errors, warnings).<\/li>\n<\/ul>\n<p>Preprocessor directives are the functions of the preprocessor. They are easy to identify as they begin with the hash character #. In contrast to instructions in the actual program code, they are not terminated with a semicolon, but with the end of the line.  <\/p>\n\n<h2 class=\"wp-block-heading\" id=\"include\">Including files &#8211; #include<\/h2>\n\n<p>As you know, you integrate files such as library files via <code>#include<\/code>. This can be written as <code>#include &lt;Dateiname\/Pfad&gt;<\/code> and <code>#include \"Dateiname\/Pfad\"<\/code>: <\/p>\n<ul>\n<li><code>#include &lt;...&gt;<\/code>: The compiler searches for the file in the standard include paths. These paths usually lead to folders called &#8220;libraries&#8221; or &#8220;include&#8221;. <\/li>\n<li><code>#include \"...\"<\/code>: The compiler first searches for the file in the current directory. If it does not find it there, it continues the search in the standard include paths. <\/li>\n<\/ul>\n<p>For example, if you have created a file called config.h for your project, there is a good chance that a file with the same name already exists somewhere. In this case, you could avoid including the wrong file by saving your config.h in the folder of your &#8220;.ino&#8221; file and including it via <code>#include \"...\"<\/code>.&nbsp;<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"define\">Macros &#8211; #define<\/h2>\n\n<h3 class=\"wp-block-heading\" id=\"macros_w_o_vars\">Simple macros without passing variables<\/h3>\n\n<p>To create a macro, use #define. In its simplest form, it looks like this: <\/p>\n<p><code>#define identifier replacement<\/code><\/p>\n<p>e.g.:<\/p>\n<p><code>#define LED_PIN 10<\/code><\/p>\n<p>By simple macros, I mean macros without any further passing of variables. In this case, <code>#define<\/code> basically does the same as the search and replace function of a word-processing program. The identifier (officially: the macro name) <code>LED_PIN<\/code> is replaced by 10 everywhere in your program. In the compiled program, it is no longer possible to see whether the 10 or the identifier was used in the source code.   <\/p>\n<p>On &#8220;spelling&#8221;: it is common practice to write macro names in capital letters. Of course, it also works with lower case letters, but you will be doing yourself and others a favor if you stick to such conventions. <\/p>\n<p>In the depths of the libraries belonging to the Arduino package, you will see many macro names that begin and sometimes end with one or two underscores, such as &#8220;__AVR_ATmega328P__&#8221;, &#8220;_VECTORS_SIZE&#8221; or &#8220;__PACKED_STRUCT&#8221;. The underscores provide a certain level of protection &#8211; as long as you do not use them yourself.  <\/p>\n\n<h4 class=\"wp-block-heading\" id=\"stumbling_blocks\">Pitfalls with simple macros<\/h4>\n\n<p>The &#8220;replacement&#8221;, i.e. the &#8220;macro value&#8221;, only gets its data type in the context of the program code. Which data type you mean and which data type the compiler makes of it may be two different things. See the following little sketch:  <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"out_of_range.ino\" data-enlighter-title=\"out_of_range.ino\">#define A_DEF 30000\n#define B_DEF 30000U\n\/* alternative 1: *\/\n\/\/ static const int A_DEF = 30000;\n\/\/ static const unsigned int B_DEF = 30000;\n\/* alternative 2: *\/\n\/\/ static constexpr int A_DEF = 30000;\n\/\/ static constexpr unsigned int B_DEF = 30000;\n\n\nvoid setup() {\n    Serial.begin(115200);\n    \/\/ delay(2000); \n     \n    Serial.print(\"A_DEF + 10000: \");\n    Serial.println(A_DEF + 10000); \n    Serial.print(\"B_DEF + 10000: \");\n    Serial.println(B_DEF + 10000); \n}\n\nvoid loop() {}<\/pre>\n<p>\n\n<p>And here is the output on an ATmega328P-based board:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_out_of_range.png\"><img loading=\"lazy\" decoding=\"async\" width=\"361\" height=\"47\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_out_of_range.png\" alt=\"Preprocessor directives - output out_of_range.ino&#10;\" class=\"wp-image-23102\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_out_of_range.png 361w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_out_of_range-300x39.png 300w\" sizes=\"auto, (max-width: 361px) 100vw, 361px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of out_of_range.ino<\/figcaption><\/figure>\n\n<p><code>A_DEF<\/code> is obviously interpreted as a signed integer. Since I have chosen a board on which an integer has a size of 2 bytes, there is an overflow and correspondingly a negative result. Although the compiler issues a warning, it is easy to overlook. The numeric literal operator &#8220;U&#8221; in the definition of the macro <code>B_DEF<\/code> provides a remedy, as it tells the compiler that the value should be &#8220;unsigned&#8221;. Alternatively, you can append &#8220;L&#8221; for long, &#8220;UL&#8221; for unsigned long, F for float or D for double. Lower case is also possible.     &nbsp;<\/p>\n<p>Another obvious pitfall is the name collision. The compiler warns of a &#8220;redefinition&#8221; in such a case, but it does not lead to termination. Therefore, it can also easily be overlooked. <\/p>\n\n<h4 class=\"wp-block-heading\" id=\"alternatives_to_define\">Alternatives to #define (const\/constexpr, enum)<\/h4>\n\n<h5 class=\"wp-block-heading\">const and constexpr<\/h5>\n\n<p>The use of constants (<code>const<\/code>) or constant expressions (<code>constexpr<\/code>) is preferable to simple <code>#define<\/code> directives, especially for larger programs. They express much more clearly what the values mean. &nbsp;<\/p>\n<p>On the difference <code>const<\/code> vs. <code>constexpr<\/code>: A constant <code>const<\/code> may be assigned its value during runtime, with a constant expression <code>constexpr<\/code> must happen during compilation.<\/p>\n<p>The addition <code>static<\/code> ensures that a constant is only initialized once, and <code>static<\/code> can also prevent the constant from being visible in other files. The exact effect of <code>static<\/code> depends on where exactly the constant has been defined (e.g. inside or outside of functions and classes). However, this goes too far here.  <\/p>\n\n<h5 class=\"wp-block-heading\">enum <\/h5>\n\n<p>You use an enumeration <code>enum<\/code> for constants that form a group, such as the primary colors in this example:<\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">enum COLOR {\n    RED   = 0xFF000,  \/\/ RGB-value\n    GREEN = 0x00FF00,\n    BLUE  = 0x0000FF\n};\n\nvoid setup() {\n  Serial.begin(115200);\n  COLOR myFavoriteColor = GREEN;\n  if (myFavoriteColor == GREEN){\n    Serial.println(\"My favorite color is green\");\n  }\n}\n\nvoid loop () {}<\/pre>\n<p>\n\n<p>Often it is not a matter of assigning specific values to the <code>enum<\/code> elements, but simply of having an identifier, e.g:<\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">enum DAY_OF_THE_WEEK {\n    MON, TUE, WED, THU, FRI, SAT, SUN\n};<\/pre>\n<p>\n\n<h3 class=\"wp-block-heading\" id=\"macros_w_vars\">Macros with passing variables<\/h3>\n\n<p>The <code>#define<\/code> macros can also take variables. This still makes them a search and replace tool, but a more complex version. Here are some examples that also show a few pitfalls:  <\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"macros_with_variables.ino\" data-enlighter-title=\"macros_with_variables.ino\">#define A_PLUS_B(a,b) a+b\n#define A_PLUS_B_BETTER(a,b) (a+b)\n#define SQUARE(a) a*a\n#define SQUARE_BETTER(a) (a)*(a)\n#define MAP_RANGE(a) map(a, 0, 100, 0, -500)\n#define MAKE_STRING(a) #a\n#define MERGE(a,b) a##b\n\nvoid setup() {\n    Serial.begin(115200);\n    \/\/ delay(2000); \n     \n    Serial.print(\"3 * A_PLUS_B(1,2):        \");\n    Serial.println(3 * A_PLUS_B(1,2));\n    \n    Serial.print(\"3 * A_PLUS_B_BETTER(1,2): \");\n    Serial.println(3 * A_PLUS_B_BETTER(1,2));\n\n    Serial.print(\"SQUARE(1+2):              \");\n    Serial.println(SQUARE(1+2));\n\n    Serial.print(\"SQUARE_BETTER(1+2):       \");\n    Serial.println(SQUARE_BETTER(1+2));\n\n    Serial.print(\"MAP_RANGE(50):            \");\n    Serial.println(MAP_RANGE(50));\n\n    Serial.print(\"MAKE_STRING(ABC123):      \");\n    Serial.println(MAKE_STRING(ABC123));\n    \n    String mergedString(MERGE(1,2)); \/\/ = String mergedString(12);\n    Serial.print(\"MERGE(1,2) as String:     \");\n    Serial.println(mergedString);\n    \n    int mergedInt = MERGE(1,2); \/\/ = int mergedInt = 12;\n    Serial.print(\"MERGE(1,2) as Integer:    \");\n    Serial.println(mergedInt);  \n}\n\nvoid loop() {}<\/pre>\n<\/div>\n<p>\n\n<p>Here is the output:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_macros-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"149\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_macros-1.png\" alt=\"Preprocessor directives - output of macros_with_variables.ino\" class=\"wp-image-23185\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_macros-1.png 512w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_macros-1-300x87.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of macros_with_variables.ino<\/figcaption><\/figure>\n\n<p>And here are a few explanations:<\/p>\n<ul>\n<li><code>A_PLUS_B(1,2)<\/code> is replaced by <code>1+2<\/code>.\n<ul>\n<li>Pitfall: <code>3*1+2<\/code> is 5!<\/li>\n<\/ul>\n<\/li>\n<li><code>A_PLUS_B_BETTER(1,2)<\/code> is replaced by <code>(1+2)<\/code>.\n<ul>\n<li>So: <code>3*(1+2) = 9<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li><code>SQUARE(1+2)<\/code> is replaced by <code>1+2*1+2<\/code> \u2192 pitfall!<\/li>\n<li><code>SQUARE_BETTER(1+2)<\/code> is replaced by <code>(1+2)*(1+2)<\/code> and returns the expected result.<\/li>\n<li><code>MAP_RANGE(50)<\/code> is replaced by <code>map(50, 0, 100, 0, -500);<\/code>.<\/li>\n<li><code>MAKE_STRING(ABC123)<\/code> is replaced by the character string <code>ABC123<\/code>.&nbsp; <br><ul>\n<li>The hash character # preceeding the &#8220;a&#8221; is an operator that instructs the preprocessor to replace &#8220;a&#8221; with a character string.<\/li>\n<\/ul>\n<\/li>\n<li><code>MERGE(1,2)<\/code> is replaced by <code>12<\/code>.\n<ul>\n<li>The operator ## concatenates a and b.<\/li>\n<li>The datatype of &#8220;12&#8221; is determined by the context (here: integer or string)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n<h4 class=\"wp-block-heading\" id=\"macros_vs_functions\">macros vs. functions<\/h4>\n\n<p>In the last example, we passed integer values to the macro <code>A_PLUS_B<\/code> as parameters. The cool thing is that the macro also works with float variables or strings. And the whole thing in a single-line definition! To achieve the same with a function would be a bit more complex. You can either solve this by overloading:    <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"overload.ino\" data-enlighter-title=\"overload.ino\">void setup() {\n    Serial.begin(115200);\n\n    int aInt = 1;\n    int bInt = 2; \n    int cInt = aPlusB(aInt, bInt);\n    Serial.print(\"aPlusB(aInt,bInt) = \");\n    Serial.println(cInt);\n\n    String aStr = \"1\";\n    String bStr = \"2\";\n    String cStr = aPlusB(aStr, bStr); \n    Serial.print(\"aPlusB(aStr,bStr) = \");\n    Serial.println(cStr);    \n}\nvoid loop() {}\n\nint aPlusB(int a, int b) {\n    return a+b;\n}\n\nString aPlusB(String a, String b) {\n    return a+b;\n}<\/pre>\n<p>\n\n<p>&#8230; or you apply templates:<\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"templates.ino\" data-enlighter-title=\"templates.ino\">void setup() {\n    Serial.begin(115200);\n\n    int aInt = 1;\n    int bInt = 2; \n    int cInt = aPlusB&lt;int&gt;(aInt, bInt);\n    Serial.print(\"aPlusB(aInt,bInt) = \");\n    Serial.println(cInt);\n\n    String aStr = \"1\";\n    String bStr = \"2\";\n    String cStr = aPlusB&lt;String&gt;(aStr, bStr); \n    Serial.print(\"aPlusB(aStr, bStr) = \");\n    Serial.println(cStr);    \n}\nvoid loop() {}\n\ntemplate &lt;typename T&gt;\nT aPlusB(T a, T b) {    \n    return a+b;\n}<\/pre>\n<p>\n\n<p>Both variants provide the following output:<\/p>\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"311\" height=\"42\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_template_ino.png\" alt=\"Output on overload.ino and template.ino\" class=\"wp-image-23169\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_template_ino.png 311w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_template_ino-300x41.png 300w\" sizes=\"auto, (max-width: 311px) 100vw, 311px\" \/><figcaption class=\"wp-element-caption\">Output of overload.ino and template.ino<\/figcaption><\/figure>\n\n<p>Overloading and templates require more effort, but these variants are simply safer. The following, for example, is accepted by the macro <code>A_PLUS_B<\/code> (or the compiler) without complaint: <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">String a = \"1\";\nint b = 2;\nSerial.println(A_PLUS_B(a, b));<\/pre>\n<p>\n\n<p>Maybe that&#8217;s what you wanted &#8211; or maybe it was an oversight.<\/p>\n\n<h4 class=\"wp-block-heading\" id=\"arduino_macros\">&#8220;Arduino macros&#8221;<\/h4>\n\n<p>The Arduino program package makes extensive use of macros. Some of them just shall make the program code easier to understand. For example, LOW and INPUT simply mean 0, OUTPUT and HIGH are 1.  <\/p>\n\n<p>Then there is a series of &#8220;function-macros&#8221;. A simple example is the &#8220;min&#8221; macro, which returns the smaller of two values you passed to it:  <\/p>\n<p><code>#define min(a,b) ((a)&lt;(b)?(a):(b))<\/code><\/p>\n\n<p>However, some of the macros are also quite complex and make use of other macros. One example of this is the &#8220;F&#8221; macro that you know from <code>Serial.print(F(\"......\"));<\/code>: <\/p>\n\n<p><code>#define F(string_literal) (reinterpret_cast&lt;const __FlashStringHelper *&gt;(PSTR(string_literal)))<\/code><\/p>\n<p>It uses the PSTR macro:<\/p>\n<p><code>#define PSTR(s) ((const PROGMEM char *)(s))<\/code><\/p>\n\n<h3 class=\"wp-block-heading\" id=\"predef_macros\">Predefined macros<\/h3>\n\n<p>Predefined macros are part of the preprocessor and are not defined via <code>#define<\/code>. The most common predefined macros can be found in the following sketch: <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"predef_macros.ino\" data-enlighter-title=\"predef_macros.ino\">void setup() {\n    Serial.begin(115200);\n    Serial.print(\"Date: \");\n    Serial.println(__DATE__); \/\/ Compiling date\n    Serial.print(\"Time: \");\n    Serial.println(__TIME__); \/\/ Compiling time\n    Serial.print(\"File: \");\n    Serial.println(__FILE__); \/\/ Compiled file\n    Serial.print(\"Line: \");\n    Serial.println(__LINE__); \/\/ Current line\n    Serial.print(\"C++ : \");\n    Serial.println(__cplusplus); \/\/ C++ Version (201103 = ISO C++ 2011)\n}\n\nvoid loop() {}<\/pre>\n<p>\n\n<p>Here is the output:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_predef_macros.png\"><img loading=\"lazy\" decoding=\"async\" width=\"665\" height=\"95\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_predef_macros.png\" alt=\"Predefined preprocessor directives - output predef_macros.ino\" class=\"wp-image-23176\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_predef_macros.png 665w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_predef_macros-300x43.png 300w\" sizes=\"auto, (max-width: 665px) 100vw, 665px\" \/><\/a><figcaption class=\"wp-element-caption\">Output predef_macros.ino<\/figcaption><\/figure>\n\n<h2 class=\"wp-block-heading\" id=\"conditional_inclusion\">Conditional inclusion of code &#8211; #ifdef, #ifndef &amp; Co<\/h2>\n\n<p>You can use <code>#define<\/code> to include parts of the source code or have them ignored by the compiler.<\/p>\n<p><code>#ifdef MACRO_NAME<\/code> checks whether <code>MACRO_NAME<\/code> has been defined or not. If <code>MACRO_NAME<\/code> has been defined, the subsequent lines of code are included. With <code>#ifndef<\/code> it is exactly the opposite.  &nbsp;<\/p>\n<p>In the simplest case, there is a <code>#endif<\/code> in the rest of the source code, which ends the conditional inclusion. However, branching is also possible with <code>#else<\/code> or <code>#elif<\/code>. In principle, it is exactly as you know it from <code>if<\/code>, <code>else<\/code> and <code>else if<\/code>. Nesting is also possible. However, this can quickly become confusing.     <\/p>\n<p>Equivalent to <code>#ifdef MACRO_NAME<\/code> is <code>#if defined(MACRO_NAME)<\/code>. This notation is used for logical operations, such as <code>#if defined(NAME_1) &amp;&amp; defined(NAME_2)<\/code>. You can also use <code>#if<\/code> to check other logical conditions, such as <code>#if A&gt;B<\/code> or <code>#if !(A==B)<\/code>.  <\/p>\n<p>At the end, each <code>#if<\/code>, <code>#ifdef<\/code> or <code>#ifndef<\/code> must be completed by <code>#endif<\/code>.&nbsp;<\/p>\n<p>A <code>#undef MACRO_NAME<\/code> does what you would expect: it terminates the definition of <code>MACRO_NAME<\/code>.<\/p>\n\n<p>Here is an example sketch:<\/p>\n<\/p>\n<div class=\"scroll-paragraph\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"conditional_inclusion.ino\" data-enlighter-title=\"conditional_inclusion.ino\">#define YIN\n#define YANG\n\nvoid setup() {\n    Serial.begin(115200);\n    \/\/ delay(2000); \n\n#ifdef YIN  \/\/ or: #if defined(YIN)\n    Serial.println(\"YIN is defined\");\n#elif defined(YANG)\n    Serial.println(\"YIN is not defined, but YANG\");\n#endif\n\n#ifdef YANG\n    Serial.println(\"YANG is defined\");\n#else \n    Serial.println(\"YANG is not defined, YIN might be defined\");\n#endif\n\n#ifndef YANG\n    Serial.println(\"YANG is not defined\");\n#endif\n\n#if defined(YIN) || defined(YANG)\n    Serial.println(\"YIN and \/ or YANG are defined\");\n#endif\n\n#if defined(YIN) &amp;&amp; defined(YANG)\n    Serial.println(\"YIN and YANG are defined\");\n#elif defined(YIN) \n    Serial.println(\"Only YIN is defined\");\n#endif\n\n#undef YANG\n#ifndef YANG\n    Serial.println(\"YANG is not defined (anymore?)\");\n#endif\n\n}\n\nvoid loop() {}<\/pre>\n<p>\u00a0<\/p>\n<\/div>\n<p>\n\n<p>The sketch provides the following output:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_conditional_inclusion.png\"><img loading=\"lazy\" decoding=\"async\" width=\"410\" height=\"97\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_conditional_inclusion.png\" alt=\"Preprocessor directives - output conditional_inclusion.ino\" class=\"wp-image-23189\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_conditional_inclusion.png 410w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_conditional_inclusion-300x71.png 300w\" sizes=\"auto, (max-width: 410px) 100vw, 410px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of conditional_inclusion.ino<\/figcaption><\/figure>\n\n<p>If you like, you can now comment out <code>#define YIN<\/code> and \/ or <code>#define YANG<\/code> and see how the output changes. <\/p>\n\n<h3 class=\"wp-block-heading\" id=\"example_double_incl\">Application example 1: Avoiding double reading of files<\/h3>\n\n<p>As a concrete example, let&#8217;s take a look at the SPI library file SPI.h of the Arduino Renesas package<a href=\"https:\/\/github.com\/arduino\/ArduinoCore-renesas\/blob\/main\/libraries\/SPI\/SPI.h\" target=\"_blank\" rel=\"noopener\">( you can find ithere<\/a> ). Many libraries of SPI-based components include SPI.h automatically. If you use several components, SPI.h could be read in several times. This is prevented by including the entire code in SPI.h with the following construction:   <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">#ifndef _SPI_H_INCLUDED\n#define _SPI_H_INCLUDED\n...... Code ........\n#endif\n<\/pre>\n<p>\n\n<p><code>_SPI_H_INCLUDED<\/code> can only be defined once, and therefore the code can only be read once.<\/p>\n\n<h3 class=\"wp-block-heading\" id=\"example_debugging\">Application example 2: Debugging<\/h3>\n\n<p>In the development phase of a project, it can be useful to output intermediate values, sensor settings, status data or similar on the serial monitor. On the other hand, <code>Serial.print()<\/code> instructions in particular are both slow and memory-hungry. In such cases, it is advisable to &#8220;switch on&#8221; or &#8220;switch off&#8221; this code using conditional inclusion.   There are many libraries that offer such a debug option.  <\/p>\n<p>However, there is another stumbling block here. Take a look at the following simple example. The main sketch uses the function <code>sumUp()<\/code>, which is defined in sum.h and sum.cpp. <code>sumUp()<\/code> simply adds three numbers. If <code>DEBUG<\/code> is defined, the intermediate steps should be output, otherwise only the final result.     <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"sum_example\" data-enlighter-title=\"sum.h\">\/\/ #define DEBUG\n\/\/ #include \"sum_config.h\"\n#include \"Arduino.h\"\n#ifndef _SUM_UP\n#define _SUM_UP\nint sumUp(int, int, int);\n#endif<\/pre>\n<p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"sum_example\" data-enlighter-title=\"sum.cpp\">#include \"sum.h\"\nint sumUp(int s1, int s2, int s3){\n    int result = 0;\n    result += s1;\n#ifdef DEBUG\n    Serial.print(\"Interim sum 1: \");\n    Serial.println(result);\n#endif\n    result += s2;\n#ifdef DEBUG\n    Serial.print(\"Interim sum 2: \");\n    Serial.println(result);\n#endif\n    result += s3;\n    return result;\n}\n<\/pre>\n<p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"sum_example\" data-enlighter-title=\"sum_config.h\">#ifndef _SUM_CONF\n#define _SUM_CONF\n\/\/ uncomment the following line to activate DEBUG\n\/\/ #define DEBUG\n#endif<\/pre>\n<p>\n\n<p>If you run the sketch as it is, you may expect the detailed output (bottom left), as <code>DEBUG<\/code> is defined in the main sketch. However, you will get the output on the right. <\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_sum_main.png\"><img loading=\"lazy\" decoding=\"async\" width=\"470\" height=\"53\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_sum_main.png\" alt=\"Output of sum_main.ino with and without DEBUG\" class=\"wp-image-23110\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_sum_main.png 470w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_sum_main-300x34.png 300w\" sizes=\"auto, (max-width: 470px) 100vw, 470px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of sum_main.ino with and without DEBUG<\/figcaption><\/figure>\n\n<p>The problem is that the preprocessor does not adhere to the sequence, but executes the <code>#include<\/code> directives first. You can solve the problem by uncommenting <code>#define DEBUG<\/code> in sumUp.h. To make it easier for the user and to minimize the risk of accidentally commenting out something incorrect, configuration files are often used in such cases. Therefore, alternatively uncomment <code>#include \"sum_config.h\"<\/code> in sum.h and <code>#define DEBUG<\/code> in sum_config.h.   <\/p>\n\n<h3 class=\"wp-block-heading\" id=\"example_mcu_specific_code\">Application example 3: MCU-specific code<\/h3>\n\n<p>The Arduino ecosystem tries to make code as universal as possible, i.e. independent of the board or microcontroller (MCU) used. Nevertheless, there are things that do not work (equally) everywhere, such as SoftwareSerial. As a concrete example, let&#8217;s take a look at an example sketch of the DFRobotDFPlayerMini library(click <a href=\"https:\/\/github.com\/DFRobot\/DFRobotDFPlayerMini\/blob\/master\/examples\/GetStarted\/GetStarted.ino\" target=\"_blank\" rel=\"noopener\">here<\/a> for the full sketch).  <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">#if (defined(ARDUINO_AVR_UNO) || defined(ESP8266))   \/\/ Using a soft serial port\n#include &lt;SoftwareSerial.h&gt;\nSoftwareSerial softSerial(\/*rx =*\/4, \/*tx =*\/5);\n#define FPSerial softSerial\n#else\n#define FPSerial Serial1\n#endif<\/pre>\n<p>\n\n<p>Only if the board is an AVR-based Arduino UNO (e.g. R3) or an ESP8266-based board, SoftwareSerial is included and the object <code>softSerial<\/code> is created, otherwise <code>Serial1<\/code> (HardwareSerial) is used. <code>softSerial<\/code> or <code>Serial1<\/code> are renamed to <code>FPSerial<\/code> so that no distinction needs to be made between HardwareSerial and SoftwareSerial in the further course. <\/p>\n<p>However, the example also shows that there are pitfalls. For example, the sketch does not work with an Arduino Nano (Classic) or an Arduino Pro Mini. They are not an Arduino UNO, they are not ESP8266-based, they do not have <code>Serial1<\/code> and therefore fall through the cracks. I would rather have chosen <code>__AVR_ATmega328P__<\/code> or <code>ARDUINO_ARCH_AVR<\/code> as <code>ARDUINO_AVR_UNO<\/code>.   <\/p>\n\n<h4 class=\"wp-block-heading\" id=\"find_defines\">Where can I find the board or MCU #defines?<\/h4>\n\n<p>Unfortunately, there is not <em>the one<\/em> big table where you can find all the definitions for the different architectures, boards and microcontrollers (at least I haven&#8217;t found one). But you can help yourself in other ways: <\/p>\n<p>Set up the board of your choice in the Arduino IDE and compile any sketch. Then click on the window with the compiler messages and click CTRL\/f. Enter &#8220;-D&#8221; in the search window. This marks the places where definitions are located (their origin is: board.txt and platform.txt). You might have to scroll to the right to find the marked locations.    <\/p>\n<p>For a WEMOS D1 Mini Board I found the definitions in the following line (shortened output):<\/p>\n<p>C:\\Users\\Ewald\\AppData\\Local\\Arduino15\\packages\\esp8266\\&#8230;&#8230;..-D<span style=\"color: #0000ff;\">ESP8266<\/span>&#8230;..-D<span style=\"color: #0000ff;\">ARDUINO_ESP8266_WEMOS_D1MINI <\/span>-D<span style=\"color: #0000ff;\">ARDUINO_ARCH_ESP8266<\/span>&#8230;..<\/p>\n<p>This is what it looked like on the screen:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_compiler_wemos_d1_mini-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"860\" height=\"35\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_compiler_wemos_d1_mini-1.png\" alt=\"\" class=\"wp-image-23117\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_compiler_wemos_d1_mini-1.png 860w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_compiler_wemos_d1_mini-1-300x12.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_compiler_wemos_d1_mini-1-768x31.png 768w\" sizes=\"auto, (max-width: 860px) 100vw, 860px\" \/><\/a><figcaption class=\"wp-element-caption\">Excerpt of compiler messages for WEMOS D1 mini board <\/figcaption><\/figure>\n\n<p>What you will not find in this way, for example, are the definitions for the various AVR microcontrollers. The io.h file from the compiler files can help here. Where exactly it is located depends on your installation. Look where your &#8220;packages&#8221; are located. For me, the path looks like this:    <\/p>\n<p>C:\\Users\\Ewald\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino5\\avr\\include\\avr\\io.h<\/p>\n\n<p>Here is a compilation of definitions for various boards:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/board_mcu_define_examples-1024x378.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"378\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/board_mcu_define_examples-1024x378.png\" alt=\"Preprocessor directives: #defines for different boards\" class=\"wp-image-23125\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/board_mcu_define_examples-1024x378.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/board_mcu_define_examples-300x111.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/board_mcu_define_examples-768x283.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/board_mcu_define_examples-1320x487.png 1320w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/board_mcu_define_examples.png 1328w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Examples of board and microcontroller definitions<\/figcaption><\/figure>\n\n<h2 class=\"wp-block-heading\" id=\"warnings_errors\">Warnings and errors &#8211; #warning, #error<\/h2>\n\n<p>With the preprocessor directive <code>#warning<\/code> &#8211; surprise! &#8211; you issue a warning. You will normally attach a condition to this. The warning has no further consequences for the compilation process.   <\/p>\n<p>The preprocessor directive <code>#error<\/code> does the same as <code>#warning<\/code>, but leads to a compiler abort. Here is a simple example: <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"warning_error.ino\" data-enlighter-title=\"warning_error.ino\">#define ARRAY_SIZE 10\n#define NUMBER_OF_ARRAYS 42\n#if ARRAY_SIZE * NUMBER_OF_ARRAYS &gt; 400\n#warning You might run out of memory!\n\/\/ #error You will run out of memory!\n#endif\n\nvoid setup() {}\n\nvoid loop() {}<\/pre>\n<p>\n\n<p>These are the resulting outputs: <\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/warning.png\"><img loading=\"lazy\" decoding=\"async\" width=\"946\" height=\"60\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/warning.png\" alt=\"Example output Preprocessor directive #warning \" class=\"wp-image-23132\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/warning.png 946w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/warning-300x19.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/warning-768x49.png 768w\" sizes=\"auto, (max-width: 946px) 100vw, 946px\" \/><\/a><figcaption class=\"wp-element-caption\">#warning output <\/figcaption><\/figure>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error.png\"><img loading=\"lazy\" decoding=\"async\" width=\"846\" height=\"117\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error.png\" alt=\"Example output Preprocessor directive #error \" class=\"wp-image-23134\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error.png 846w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error-300x41.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error-768x106.png 768w\" sizes=\"auto, (max-width: 846px) 100vw, 846px\" \/><\/a><figcaption class=\"wp-element-caption\">#error output<\/figcaption><\/figure>\n\n<h2 class=\"wp-block-heading\" id=\"line\">Manipulating the line counter and file name &#8211; #line<\/h2>\n\n<p>The preprocessor &#8220;knows&#8221; which file and which program line it is currently processing. You can change both with <code>#line line_number \"file_name\"<\/code>. However, I don&#8217;t know why one should do this (except to annoy others!).   <\/p>\n\n<p>However, here is an example:<\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"line_example.ino\" data-enlighter-title=\"line_example.ino\">void setup() {\n\/\/#line 33 \"blabla.h\"    \n    int i = 42!;\n}\n\nvoid loop() {}<\/pre>\n<p>\n\n<p>This is the normal output:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error_w_o_line.png\"><img loading=\"lazy\" decoding=\"async\" width=\"855\" height=\"160\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error_w_o_line.png\" alt=\"\" class=\"wp-image-23127\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error_w_o_line.png 855w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error_w_o_line-300x56.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error_w_o_line-768x144.png 768w\" sizes=\"auto, (max-width: 855px) 100vw, 855px\" \/><\/a><figcaption class=\"wp-element-caption\">&#8220;Normal&#8221; error message<\/figcaption><\/figure>\n\n<p>And here is the manipulated version:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error_with_line.png\"><img loading=\"lazy\" decoding=\"async\" width=\"623\" height=\"120\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error_with_line.png\" alt=\"\" class=\"wp-image-23129\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error_with_line.png 623w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/error_with_line-300x58.png 300w\" sizes=\"auto, (max-width: 623px) 100vw, 623px\" \/><\/a><figcaption class=\"wp-element-caption\">Error message, manipulated with #line<\/figcaption><\/figure>\n\n<h2 class=\"wp-block-heading\" id=\"pragma\">The multifunctional tool &#8211; #pragma<\/h2>\n\n<p>The <code>#pragma<\/code> directives are versatile, but not standardized. This means that every compiler implementation can in principle define its own <code>#pragma<\/code> directives. On the one hand, this means that I cannot provide a complete overview, and on the other hand, it means that I cannot guarantee that all the directives presented here are compatible with every compiler. However, it should work with the compilers of the Arduino IDE for the common boards (e.g. AVR, Renesas, ESP32, ESP8266, ARM).   &nbsp;<\/p>\n\n<h3 class=\"wp-block-heading\" id=\"pragma_once\">#pragma once<\/h3>\n\n<p>A simple <code>#pragma once<\/code> at the beginning of a file ensures that it is only read in once. This is much simpler than the conventional method of enclosing the entire file content with a <code>#ifndef<\/code> &#8211; <code>#def<\/code> &#8211; <code>endif<\/code> construction.  <\/p>\n\n<h3 class=\"wp-block-heading\" id=\"pragma_poison\">#pragma poison<\/h3>\n\n<p>You can use <code>#pragma poison<\/code> to mark identifiers, functions or character strings as &#8220;poison&#8221;. The compiler aborts when it encounters these.  Here is an example:<\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"pragma_poison.ino\" data-enlighter-title=\"pragma_poison.ino\">#pragma GCC poison blablabla\n\nvoid setup() {\n    Serial.begin(115200);\n    String blablabla = \"Nice to see you\";\n}\n\nvoid loop() {}<\/pre>\n<p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_poison.png\"><img loading=\"lazy\" decoding=\"async\" width=\"907\" height=\"120\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_poison.png\" alt=\"#pragma preprocessor directives - output pragma_poison.ino\" class=\"wp-image-23140\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_poison.png 907w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_poison-300x40.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_poison-768x102.png 768w\" sizes=\"auto, (max-width: 907px) 100vw, 907px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of pragma_poison.ino<\/figcaption><\/figure>\n\n<p>This also works with begin or &#8220;Nice to see you&#8221;, but not simply with Nice.<\/p>\n\n<h3 class=\"wp-block-heading\" id=\"pragma_msg_warn_err\">#pragma message \/ warning \/ error<\/h3>\n\n<p>The directive <code>#pragma message \"xxxxxxx\"<\/code> outputs the message &#8220;xxxxxxx&#8221; during compilation. The compilation process is not aborted. It is the same with <code>#pragma GCC warning<\/code>. <code>#pragma GCC error<\/code>, on the other hand, outputs an error and the compiler aborts the work.  <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"pragma_msg_warn_error.ino\" data-enlighter-title=\"pragma_msg_warn_error.ino\">void setup() { \n    Serial.begin(115200); \n    String blabla = \"The weather is nice\";\n    Serial.println(blabla); \n#pragma message \"This is blabla\"\n    Serial.println(blabla);\n#pragma GCC warning \"Again, this was blabla\"\n    Serial.println(blabla);\n\/\/ #pragma GCC error \"Refusing to compile this blabla any longer!\"\n}\n\nvoid loop(){}<\/pre>\n<p>\n\n<p>The output is:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_msg_warn_error_1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"913\" height=\"132\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_msg_warn_error_1.png\" alt=\"#pragma preprocessor directives - Output pragma_msg_warn_err.ino\" class=\"wp-image-23223\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_msg_warn_error_1.png 913w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_msg_warn_error_1-300x43.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_msg_warn_error_1-768x111.png 768w\" sizes=\"auto, (max-width: 913px) 100vw, 913px\" \/><\/a><figcaption class=\"wp-element-caption\">Output 1 of pragma_msg_warn_error.ino<\/figcaption><\/figure>\n\n<p>If you now uncomment line 9, you will only get the error message:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_msg_warn_error_2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1020\" height=\"120\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_msg_warn_error_2.png\" alt=\"#pragma preprocessor directives - Issue 2 of pragma_msg_warn_err.ino\" class=\"wp-image-23225\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_msg_warn_error_2.png 1020w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_msg_warn_error_2-300x35.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_msg_warn_error_2-768x90.png 768w\" sizes=\"auto, (max-width: 1020px) 100vw, 1020px\" \/><\/a><figcaption class=\"wp-element-caption\">Output 2 of pragma_msg_warn_error.ino<\/figcaption><\/figure>\n\n<h3 class=\"wp-block-heading\" id=\"pragma_diagnostic\">#pragma diagnostic<\/h3>\n\n<h4 class=\"wp-block-heading\">Suppressing warnings<\/h4>\n\n<p>The <code>#pragma GCC diagnostic<\/code> directive is used to control warnings and error messages. The various options are selected using additional parameters.  <code>#pragma GCC diagnostic ignored &lt;warning type&gt;<\/code> suppresses the warning of the type &#8220;warning type&#8221;.<\/p>\n\n<p>As an example, I return to the overflow problem that occurred with the following code (for boards with an integer size of 2 bytes):<\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"pragma_diagnostic.ino\" data-enlighter-title=\"pragma_diagnostic.ino\">\/\/#pragma GCC diagnostic ignored \"-Woverflow\"\n#define A 30000\n#define B 10000\nvoid setup() { \n    Serial.begin(115200); \n    Serial.println(A + B);\n}\n\nvoid loop(){}<\/pre>\n<p>\n\n<p>You can suppress the following warning by uncommenting the first line of the sketch:<\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diagnostic.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1013\" height=\"60\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diagnostic.png\" alt=\"Output pragma_dignostic.example\" class=\"wp-image-23273\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diagnostic.png 1013w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diagnostic-300x18.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diagnostic-768x45.png 768w\" sizes=\"auto, (max-width: 1013px) 100vw, 1013px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of pragma_diagnostic.ino<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">Suppressing warnings in a defined area \/ making errors from warnings<\/h4>\n\n<p>With <code>#pragma GCC diagnostic error &lt;warning-type&gt;<\/code> you can turn a compiler warning into a compiler error, i.e. the compiler aborts its work.<\/p>\n<p>Let&#8217;s take a look at this by the example of unused variables. You will receive a warning for these if you have selected either &#8220;More&#8221; or &#8220;All&#8221; under &#8220;Compiler warnings&#8221; in the Arduino IDE settings. With <code>#pragma GCC diagnostic error \"-Wunused-variable\"<\/code> we make an error out of it in the next sketch. As we saw before, we can suppress the message again with <code>#pragma GCC diagnostic ignore \"Wunused-variable\"<\/code>.   <\/p>\n<p>However, we can limit the suppression of the message to a selected area. This is done using <code>#pragma GCC diagnostic push<\/code> and <code>#pragma GCC diagnostic pop<\/code>. With <code>push<\/code> the compiler remembers the current warning setting, with <code>pop<\/code> it restores this state. It may sound complicated, but it is simple:   <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"pragma_diag_push_pop.ino\" data-enlighter-title=\"pragma_diag_push_pop.ino\">void setup() { \n    Serial.begin(115200);\n#pragma GCC diagnostic error \"-Wunused-variable\" \/\/ makes an error out of warning\n    int usedVar = 42;\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wunused-variable\" \n    int unusedVar = 43;  \/\/ error is inored here\n#pragma GCC diagnostic pop\n    int anotherUnusedVar = 44;  \/\/ error is not ignored here\n    Serial.println(usedVar);\n}\n\nvoid loop(){}<\/pre>\n<p>\n\n<p>Here is the output:<\/p>\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diag_push_pop-1024x162.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"162\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diag_push_pop-1024x162.png\" alt=\"#pragma preprocessor directives - Output pragma_diag_push_pop.ino\" class=\"wp-image-23214\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diag_push_pop-1024x162.png 1024w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diag_push_pop-300x47.png 300w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diag_push_pop-768x121.png 768w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_diag_push_pop.png 1153w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of pragma_diag_push_pop.ino<\/figcaption><\/figure>\n\n<p>If you comment lines 5 and 8, you will not get an error message. If you comment out lines 5, 6 and 8, you will get two error messages.  <\/p>\n\n<h3 class=\"wp-block-heading\" id=\"pragma_pack\">#pragma pack()<\/h3>\n\n<p>The following sketch defines a structure <code>exampleStruct<\/code>, which consists of two uint8_t and two uint32_t elements. The structure should therefore use 10 bytes of memory. The sketch outputs the actual memory used.  <\/p>\n<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"pragma_pack.ino\" data-enlighter-title=\"pragma_pack.ino\">\/\/#pragma pack(1)\nstruct exampleStruct{\n    uint32_t    intVal_1;    \/\/   4 Byte\n    uint8_t     byteVal_1;   \/\/ + 1 Byte\n    uint32_t    intVal_2;    \/\/ + 4 Byte\n    uint8_t     byteVal_2;   \/\/ + 1 Byte = 10 Byte (in theory!)\n};\n\nvoid setup() { \n    Serial.begin(115200);\n    Serial.print(\"Size of exampleStruct: \");\n    Serial.println(sizeof(exampleStruct));\n}\n\nvoid loop(){}<\/pre>\n<p>\n\n<p>If you run the sketch on an AVR-based board such as the Arduino UNO R3, you will get the expected 10 bytes. If you now switch to an ESP32 board or an Arduino UNO R4 (Minima or WIFI), for example, the output may surprise you: <\/p>\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_pack.png\"><img loading=\"lazy\" decoding=\"async\" width=\"504\" height=\"32\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_pack.png\" alt=\"#pragma preprocessor directives - Output pragma_pack.ino\" class=\"wp-image-23219\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_pack.png 504w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/output_pragma_pack-300x19.png 300w\" sizes=\"auto, (max-width: 504px) 100vw, 504px\" \/><\/a><figcaption class=\"wp-element-caption\">Output pragma_pack.ino on an ESP32<\/figcaption><\/figure>\n\n<p>What happens here is called padding. The larger 32-bit microcontrollers work faster if the elements of the structure are packed into four-byte blocks in such a way that, <em>if possible<\/em>, no element is spread over two or more blocks. The blocks are boxes with four compartments, so to speak, with one byte fitting into each compartment. The element <code>intVal_1<\/code> fills the first box. A new box is used for <code>byteVal_1<\/code>. The three free compartments are not sufficient for <code>intVal_2<\/code>, which is why a new box is used. <code>byteVal_2<\/code> needs another new box, the same applies to <code>intVal_2<\/code> \u2192 makes four boxes = 16 compartments = 16 bytes.      <\/p>\n<p>If you arrange the elements differently, you can save space, e.g: <code>intVal_1<\/code> \u2192 <code>byteVal_1<\/code> \u2192 <code>byteVal_2<\/code> \u2192 <code>intVal_2<\/code>. Then <code>byteVal_2<\/code> still fits into the second box, and you only use three boxes in total = 12 bytes. <\/p>\n<p>You can use <code>#pragma pack(x)<\/code> to specify the number of compartments x per box. Here x must be <sup>2n<\/sup>, i.e. x = 1, 2, 4, 8 etc. With <code>#pragma pack(1)<\/code> you can achieve the maximum packing density. Uncomment line 1 in the example sketch above to limit the size of <code>exampleStruct<\/code> to 10 bytes. If you select <code>#pragma pack(2)<\/code>, the result is 12 bytes. The default setting therefore corresponds to <code>#pragma pack(4)<\/code>.    <\/p>\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Preprocessor directives determine what the compiler shall ultimately process. To do this, they replace character strings and include or exclude lines of code. They also influence the behavior of the compiler.   <\/p>\n","protected":false},"author":1,"featured_media":23237,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[567,575],"tags":[2646,2652,2651,2656,2658,2647,2650,2648,2649,2653,2659,2660,2657,556,2664,2654,2663,2662,2667,2666,2668,2661,2665,2655,2645],"class_list":["post-23280","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-other-stuff","category-software-and-tools","tag-define-en","tag-elif-en","tag-else-en","tag-endif-en","tag-error-en","tag-if-en","tag-if-defined-en","tag-ifdef-en","tag-ifndef-en","tag-include-en","tag-line-en","tag-pragma-en","tag-warning-en","tag-arduino-en-2","tag-diagnostic-en","tag-macros-vs-functions","tag-message-en","tag-once-en","tag-pack-en-2","tag-pack-en","tag-padding-en","tag-poison-en","tag-pop-en","tag-predefined-macros","tag-preprocessor-directives"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Preprocessor directives &#8226; Wolles Elektronikkiste<\/title>\n<meta name=\"description\" content=\"Preprocessor directives replace character strings, include or exclude parts of code or complete files, and influence the behavior of the compiler.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Preprocessor directives &#8226; Wolles Elektronikkiste\" \/>\n<meta property=\"og:description\" content=\"Preprocessor directives replace character strings, include or exclude parts of code or complete files, and influence the behavior of the compiler.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives\" \/>\n<meta property=\"og:site_name\" content=\"Wolles Elektronikkiste\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-18T21:09:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-09-10T18:54:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/preprocessor_directives_image.png\" \/>\n\t<meta property=\"og:image:width\" content=\"985\" \/>\n\t<meta property=\"og:image:height\" content=\"985\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Wolfgang Ewald\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wolfgang Ewald\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives\"},\"author\":{\"name\":\"Wolfgang Ewald\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"headline\":\"Preprocessor directives\",\"datePublished\":\"2025-02-18T21:09:56+00:00\",\"dateModified\":\"2025-09-10T18:54:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives\"},\"wordCount\":3116,\"commentCount\":6,\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/preprocessor_directives_image.png\",\"keywords\":[\"#define\",\"#elif\",\"#else\",\"#endif\",\"#error\",\"#if\",\"#if defined\",\"#ifdef\",\"#ifndef\",\"#include\",\"#line\",\"#pragma\",\"#warning\",\"Arduino\",\"diagnostic\",\"macros vs. functions\",\"message\",\"once\",\"pack\",\"pack()\",\"padding\",\"poison\",\"pop\",\"Predefined macros\",\"Preprocessor directives\"],\"articleSection\":[\"Other stuff\",\"Software and tools\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives\",\"name\":\"Preprocessor directives &#8226; Wolles Elektronikkiste\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/preprocessor_directives_image.png\",\"datePublished\":\"2025-02-18T21:09:56+00:00\",\"dateModified\":\"2025-09-10T18:54:59+00:00\",\"description\":\"Preprocessor directives replace character strings, include or exclude parts of code or complete files, and influence the behavior of the compiler.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives#primaryimage\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/preprocessor_directives_image.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2025\\\/02\\\/preprocessor_directives_image.png\",\"width\":985,\"height\":985},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/preprocessor-directives#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Preprocessor directives\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\",\"name\":\"Wolles Elektronikkiste\",\"description\":\"Die wunderbare Welt der Elektronik\",\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\",\"name\":\"Wolfgang Ewald\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"width\":512,\"height\":512,\"caption\":\"Wolfgang Ewald\"},\"logo\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Preprocessor directives &#8226; Wolles Elektronikkiste","description":"Preprocessor directives replace character strings, include or exclude parts of code or complete files, and influence the behavior of the compiler.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives","og_locale":"en_US","og_type":"article","og_title":"Preprocessor directives &#8226; Wolles Elektronikkiste","og_description":"Preprocessor directives replace character strings, include or exclude parts of code or complete files, and influence the behavior of the compiler.","og_url":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives","og_site_name":"Wolles Elektronikkiste","article_published_time":"2025-02-18T21:09:56+00:00","article_modified_time":"2025-09-10T18:54:59+00:00","og_image":[{"width":985,"height":985,"url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/preprocessor_directives_image.png","type":"image\/png"}],"author":"Wolfgang Ewald","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wolfgang Ewald","Est. reading time":"21 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives#article","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives"},"author":{"name":"Wolfgang Ewald","@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"headline":"Preprocessor directives","datePublished":"2025-02-18T21:09:56+00:00","dateModified":"2025-09-10T18:54:59+00:00","mainEntityOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives"},"wordCount":3116,"commentCount":6,"publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/preprocessor_directives_image.png","keywords":["#define","#elif","#else","#endif","#error","#if","#if defined","#ifdef","#ifndef","#include","#line","#pragma","#warning","Arduino","diagnostic","macros vs. functions","message","once","pack","pack()","padding","poison","pop","Predefined macros","Preprocessor directives"],"articleSection":["Other stuff","Software and tools"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives","url":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives","name":"Preprocessor directives &#8226; Wolles Elektronikkiste","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives#primaryimage"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/preprocessor_directives_image.png","datePublished":"2025-02-18T21:09:56+00:00","dateModified":"2025-09-10T18:54:59+00:00","description":"Preprocessor directives replace character strings, include or exclude parts of code or complete files, and influence the behavior of the compiler.","breadcrumb":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives#primaryimage","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/preprocessor_directives_image.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2025\/02\/preprocessor_directives_image.png","width":985,"height":985},{"@type":"BreadcrumbList","@id":"https:\/\/wolles-elektronikkiste.de\/en\/preprocessor-directives#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/wolles-elektronikkiste.de\/en"},{"@type":"ListItem","position":2,"name":"Preprocessor directives"}]},{"@type":"WebSite","@id":"https:\/\/wolles-elektronikkiste.de\/en#website","url":"https:\/\/wolles-elektronikkiste.de\/en","name":"Wolles Elektronikkiste","description":"Die wunderbare Welt der Elektronik","publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wolles-elektronikkiste.de\/en?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46","name":"Wolfgang Ewald","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","width":512,"height":512,"caption":"Wolfgang Ewald"},"logo":{"@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png"}}]}},"_links":{"self":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/23280","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/comments?post=23280"}],"version-history":[{"count":11,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/23280\/revisions"}],"predecessor-version":[{"id":24855,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/23280\/revisions\/24855"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media\/23237"}],"wp:attachment":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media?parent=23280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/categories?post=23280"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/tags?post=23280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}