stdarg и что здесь вообще происходит?
Написал простейший код с использованием varidatic functions
#include <stdio.h>
#include <stdarg.h>
typedef void (*callback_ft)();
void OnPlayerJoin(int, char*);
void OnPlayerDisconnect(int, char*, int);
void call(callback_ft callback, ...) {
va_list args;
va_start(args, callback);
callback(args);
va_end(args);
}
int main(int argc, char* argv[]) {
call(OnPlayerJoin, "Mike");
call(OnPlayerJoin, "Bob", "Hello"); // неправильный вызов
call(OnPlayerDisconnect, "John", 176);
call(OnPlayerDisconnect, "John"); // неправильный вызов
}
void OnPlayerJoin(int n, char* name) { printf("Hi %s!\n", name); }
void OnPlayerDisconnect(int n, char* name, int time) { printf("%s disconnected! Played for %imin\n", name, time); }
Код работает, запускается и выводит:
Но у меня возникло 3 вопроса:
- Почему при указании сигнатуры функции с пустыми параметрами, в вызываемые аргументы передаются правильно, даже с учётом того, что первый опорный параметр n явно не передаётся?
- Почему при неправильном вызове код продолжает более-менее адекватно работать не вываливаясь сразу в segfault?
- Насколько такой код переносим и насколько его опасно применять в реальных проектах?
Я действительно не понимаю как это работает и почему это вообще работает...
[Visual Studio 2022 | Стандартные настройки проекта, кроме флагов /TC и /std:c17]
Источник: Stack Overflow на русском