From 2e24376b9eb84058f00f30e227c3d9c3a4f67378 Mon Sep 17 00:00:00 2001 From: Huzaifa Sidhpurwala Date: Jun 09 2020 05:26:46 +0000 Subject: Merge #8 `Add section on the misuse of macros.` --- diff --git a/modules/ROOT/pages/programming-languages/C-Other.adoc b/modules/ROOT/pages/programming-languages/C-Other.adoc index 3d9d502..f056a3a 100644 --- a/modules/ROOT/pages/programming-languages/C-Other.adoc +++ b/modules/ROOT/pages/programming-languages/C-Other.adoc @@ -51,3 +51,85 @@ careful analysis and comparison with the compiler documentation 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. + + +