Кто-то может объяснить это поведение? всего 2 строки кода
Просьба объяснить этот фрагмент:
#include <stdio.h>
int puts(const char *str) {
fputs("Hello world!\n", stdout);
}
int main() {
printf("Goodbye\n");
}
Выход: Hello world!
return 13
Ответы
Ответ 1
Он специфичен для компилятора. Вы получаете это поведение с GCC. Вот несколько деталей.
-
так как вы #include <stdio.h>
(фактически потому, что вы находитесь в размещенной среде) puts
соответствует стандарту C99, а переопределяет его undefined
-
компилятор GCC имеет некоторые оптимизации для преобразования некоторого printf
в последовательность более быстрого puts
. Это законно, поскольку вы включили <stdio.h>
(и стандарт C99 определяет, что должен делать printf
в этом случае; GCC проходит через __builtin_printf
в качестве промежуточного шага)
Если вы скомпилируете с помощью -ffreestanding
, вы не заметите этого.
Ваш вопрос очень близок к этому; поэтому этот ответ также имеет значение.
Ответ 2
Я скомпилировал программу с помощью gcc x.c -S -o-
. Это дало мне
[...]
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:
так что вызов printf
заменяется на puts
в GCC, так как они имеют одинаковую семантику.
Ответ 3
Мое предположение заключается в том, что компилятор меняет вызов на printf()
на вызов puts()
, так как нет необходимости в printf()
из-за отсутствия форматирования. Также строка заканчивается новой строкой, которая соответствует puts()
. Компилятор не видел вашу страшную перегрузку функции библиотеки, поэтому она стала "одураченной".