-1
# include <stdio.h>
# define scanf "%s Hello "
int main()
{
  printf(scanf, scanf);
  return 0;
}

OUTPUT : %s Hello Hello

The above mentioned code gives the output that follows it. I understand that after pre-processing phase of compilation, printf statement will become. printf("%s Geeks Quiz ", "%s Geeks Quiz "). But I"m still having a hard time to know how it was further reduced to the obtained output.

Is the first statement imposed in the second or is it the other way around

I would like some help from anyone who has the idea. Thank you

I'm still an amateur, so it would be easy for me to understand a simple or detailed answer, but I would appreciate any replies.

SHASHANK N
  • 47
  • 5
  • 2
    Read about `printf` – qrdl Sep 15 '21 at 09:48
  • 2
    Macros are textually substituted before the actual compiling process, `printf(scanf, scanf);` will be seen as `printf("%s Hello ", "%s Hello ");` by the compiler. – Jabberwocky Sep 15 '21 at 09:51
  • Strictly speaking, this code invokes undefined behavior as per C17 7.1.3/2. " If the program declares or defines an identifier in a context in which it is reserved..." "...or defines a reserved identifier as a macro name, the behavior is undefined." – Lundin Sep 15 '21 at 14:18

1 Answers1

4

The preprocessor substitutes textually the following:

#define scanf "%s Hello"
int main() {
  ...
  printf(scanf, scanf);

in a way the compiler reads:

int main() {
  ...
  printf("%s Hello", "%s Hello");

At this point the program is run, and printf() receives the two strings "%s Hello".

The first argument contains a "%s", which says put the next string argument here, so the final string becomes

"%s Hello Hello"

After the first substitution of %s, made by printf() at runtime, no more %s specifiers are present, so the final result is what you see (and it is correct).

I mean: the first argument to printf() is parsed just once; if there is a single %s there, a single substitution is made. Whatever results from the single substitution is not parsed again, so the %s present in the second argument appears, unchanged.

unwind
  • 391,730
  • 64
  • 469
  • 606