#8 Add section on the misuse of macros.
Merged 4 years ago by huzaifas. Opened 4 years ago by wmealing.
wmealing/defensive-coding-guide macros-misuse  into  master

@@ -51,3 +51,85 @@ 

  is required to check if propagating the attribute is

  appropriate. Incorrectly applied attributes can result in

  undesired behavioral changes in the compiled code.

+ 

+ [[sect-Defensive_Coding-C-Common-Mistakes]]

+ === Common mistakes

+ 

+ ==== Mistakes in macros

+ A macro is a name given to a block of C statements as a pre-processor

+ directive. Being a pre-processor the block of code is transformed by

+ the compiler before being compiled.

+ 

+ A macro starts with the preprocessor directive, #define.  It can

+ define a single value or any 'substitution', syntactically valid or

+ not.

+ 

+ A common mistake when working with macros is that programmers treat

+ arguments to macros like they would functions.  This becomes an issue

+ when the argument may be expanded multiple times in a macro.

+ 

+ For example:

+ 

+ macro-misuse.c

+ [source,C]

+ ----

+ #define simple(thing) do { \

+                     if (thing < 1) { \

+                      y = thing; \

+                     } \

+                     else if (thing > 100) { \

+                      y = thing * 2 + thing; \

+                     } \

+                     else  { \

+                      y = 200; \

+                     } \

+                     } while (0)

+ 

+ int main(void) {

+      int x = 200;

+      int y = 0;

+      simple(x++);

+ 

+      return 0;

+ }

+ ----

+ 

+ Each pass through the simple() macro would mean that x could be

+ expanded in-place each time 'thing' was mentioned.

+ 

+ The 'main' function would be processed and expanded as follows:

+ 

+ macro-misuse-post-processing.c

+ [source,C]

+ ----

+ 

+   int main(void) {

+      int x = 200;

+      int y = 0;

+      do {

+                     if ( x++ < 1) {

+                      y = x++;

+                     }

+                     else if (thing > 100) {

+                      y = x++ * 2 + x++;

+                     }

+                     else  {

+                      x = 200;

+                     }

+     } while (0)

+ 

+     return 0;

+   }

+ ----

+ 

+ Each evaluation of the argument to 'simple' (x++) would be executed

+ each time it was referenced.

+ 

+ While this may be 'expected' behaviour by the original creator, large

+ projects may have programmers who were unaware of how the macro may

+ expand and this may introduce unexpected behaviour, especially if the

+ value is later used as indexing into an array or able to be

+ overflowed.

+ 

+ 

+ 

First pull ive done for this project, let me know if it should be in another location. This outlines the possible misuse of macros and the automated expansion by the c pre-processor.

Metadata Update from @huzaifas:
- Request assigned

4 years ago

Thanks for your PR, does any one want to review this one?

Pull-Request has been merged by huzaifas

4 years ago