After working for more than 10 years, today a code caught my eye, I am unable to understand the function name defined inside a function gets printed in the output/log without being passed as an argument in macro or being defined as a global variable. Please help me understanding the internal. Please see the screenshot for the reference.
/*...*/
#include <stdio.h>
#define x printf("%s", f);
int main() {
char *f = "MAIN";
printf("Hello World");
x;
return 0;
}
Output:
Hello WorldMAIN
CodePudding user response:
C preprocessor macros simply do text replacement. They have no semantic awareness of your program.
This:
#include <stdio.h>
#define x printf("%s", f);
int main()
{
char* f = "MAIN";
printf ("Hello World");
x;
return 0;
}
Becomes:
#include <stdio.h>
int main()
{
char* f = "MAIN";
printf ("Hello World");
printf("%s", f);;
return 0;
}
Please note that if there is no f
declared when this macro is used, you will see a compiler error. If f
is declared, but is not a char *
, you should see compiler warnings.
Some preprocessor macro best practices include (but are not limited to) using capitalized names, as x
by convention looks like a variable or function name; and being careful about what syntactically significant symbols (in this case ;
) you include in your macro text.
Hopefully this example was done for the sake of learning, because it is wholly unnecessary. Preprocessor macros wouldn't exist if they didn't serve a purpose, but beware they can easily obfuscate code.
CodePudding user response:
Preprocessor macros are just text replacements. All #include
statements are replaced with the content of the specified files. All occurrences of #define
'd symbols are replaced with their specified text. All comments are omitted. Etc...
So, in your example:
/*...*/
#include <stdio.h>
#define x printf("%s", f);
int main() {
char *f = "MAIN";
printf("Hello World");
x;
return 0;
}
The preprocessor replaces all instances of x
with the text printf("%s", f);
before the processed code is then sent to the compiler. So, this is the code that the compiler actually sees:
// contents of <stdio.h> here...
int main() {
char *f = "MAIN";
printf("Hello World");
printf("%s", f);;
return 0;
}