У вас должно быть другое определение слова "ошибка" :-) Что печатается в первые два раза, когда вы вызываете функцию f
? Я получаю
1 -1216175936 134513787
1 2 134513787
1 2 3
для моих трех вызовов функций.
То, что вы видите, - это пережиток с самых ранних дней C, когда люди играли с ног и без излишеств со своими вызовами функций.
Все, что происходит, это то, что вы вызываете функцию f
, и она выводит три значения из стека (да, даже если вы даете только одно или два). То, что происходит, когда вы не предоставляете достаточно, заключается в том, что ваша программа, скорее всего, просто использует то, что было в любом случае, что обычно приводит к проблемам с данными при чтении и катастрофическим сбоям при записи.
Это прекрасно компилируется, хотя и очень неразумно, C. И я имею в виду, что в очень реальном, «неопределенном поведении» смысл слова (в частности, относится к C99: «Если выражение, обозначающее вызываемую функцию, имеет тип который не включает прототип, ... если количество аргументов не равно количеству параметров, поведение не определено ").
Вы действительно должны предоставить полностью сформированные прототипы функций, такие как:
void f(int,int,int);
, чтобы гарантировать, что ваш компилятор обнаружит эту проблему и использует эллипсы (...
) в функциях переменных параметров.
Кроме того, под покровом обычно происходит то, что вызывающая функция начинается со стека, подобного:
12345678
11111111
и помещает (например) два значения в стек так, чтобы оно заканчивалось следующим образом:
12345678
11111111
2
1
Когда вызываемая функция использует первые три значения в стеке (поскольку это то, что она хочет), она обнаруживает, что она имеет 1
, 2
и 11111111
.
Он делает то, что должен делать, затем возвращает, и вызывающая функция удаляет эти два значения из стека (это называется стратегией «вызывающий делает добро»). Горе всем, кто пытается сделать это с помощью стратегии «вызывающий-делает-хорошо» :-), хотя в C это довольно необычно, поскольку делает функции с переменными аргументами, такие как printf
, немного сложными для выполнения.