9

Kindly explain this snippet:

#include <stdio.h>

int puts(const char *str) {
    fputs("Hello world!\n", stdout);
}

int main() {
    printf("Goodbye\n");
}

Output : Hello world! return 13

ani627
  • 5,578
  • 8
  • 39
  • 45

3 Answers3

10

It is compiler specific. You get this behavior with GCC. Here are some details.

  • since you #include <stdio.h> (actually because you are in a hosted environment) the puts is that of the C99 standard, and redefining it is undefined behavior

  • the GCC compiler has some optimizations to transform some printf to a sequence of faster puts. This is legal, since you have included <stdio.h> (and the C99 standard defines what printf should do in that case; GCC goes thru __builtin_printf as an intermediate step)

If you compile with -ffreestanding you won't observe that.

Your question is very close to this one; so this answer is also relevant.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
7

I compiled the program with gcc x.c -S -o-. It gave me

[...]
main:
.LFB1:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        andl    $-16, %esp
        subl    $16, %esp
        movl    $.LC1, (%esp)
        call    puts
        leave
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc
.LFE1:

so indeed the printf call is replaced with puts in GCC, as they have the same semantics.

glglgl
  • 89,107
  • 13
  • 149
  • 217
6

My guess would be that the compiler changes the call to printf() into a call to puts(), since there's no need for printf() due to no formatting. Also the string is terminated by a newline, which fits puts(). The compiler didn't see your scary overload of a library function coming, so it got "fooled".

unwind
  • 391,730
  • 64
  • 469
  • 606