Я предполагаю, что вы компилируете
main(){ printf("%d");}
Это выберет случайное значение из текущего стека. Попробуйте это:
main() {
printf("%d", 0);
printf("%d");
}
Теперь второй printf()
всегда будет печатать 0
, поскольку он получает тот же стек, что и первый вызов.
[EDIT] Это не работает на x86 Linux с GCC 4.1.2. Вот сгенерированный ассемблерный код (используйте gcc -S -o t.s t.c
):
movl $0, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $.LC0, %edi
movl $0, %eax
call printf
Как видите, второй аргумент не помещается в стек, а передается через %esi
(который является регистром). Этот же регистр, вероятно, изменен в printf()
, поэтому он теряет свое значение. Чертовы оптимизации;)