История изменений
Исправление KivApple, (текущая версия) :
Не-а. Где ты увидел у этой функции переменное число аргументов? va_start/va_end делает другая функция, которая имеет действительно переменное число аргументов.
Сейчас приведу простой пример:
int vprintf(const char *fmt, va_list arg) {
...
}
int printf(const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
int r = vprintf(fmt, arg);
va_end(arg);
return r;
}
Именно такая логика у функций printf/vprintf в libc (разумеется, я всё упростил для наглядности).
Функция с переменным числом аргументов часто является лишь обёрткой над функцией принимающей va_list. Зачем это нужно? Например, за этим:
int debug_printf(const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
fprintf(stderr, "DEBUG: ");
int r = vfprintf(stderr, fmt, arg);
va_end(arg);
return r;
}
Опять же банальный пример, чтобы просто понять логику (ещё например, с помощью vsnprintf можно легко запилить свою реализацию asprintf). В общем, я всё правильно делаю (кроме того что пытаюсь получить bool через va_arg).
В реальном коде у меня было что-то подобное (была обёртка вокруг функции, которая принимала va_list), однако для рассматриваемого бага это не имеет никакого значения. Да, func нельзя вызывать напрямую, а надо через обёртку, которой нет, но суть то в том, что код некорректный генерируется (а обёртка гипотетически может быть в другом файле, так что на кодогенерацию её отсутствие не должно влиять).
Исправление KivApple, :
Не-а. Где ты увидел у этой функции переменное число аргументов? va_start/va_end делает другая функция, которая имеет действительно переменное число аргументов.
Сейчас приведу простой пример:
int vprintf(const char *fmt, va_list arg) {
...
}
int printf(const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
int r = vprintf(fmt, arg);
va_end(arg);
return r;
}
Именно такая логика у функций printf/vprintf в libc (разумеется, я всё упростил для наглядности).
Функция с переменным числом аргументов часто является лишь обёрткой над функцией принимающей va_list. Зачем это нужно? Например, за этим:
int debug_printf(const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
fprintf(stderr, "DEBUG: ");
int r = vfprintf(stderr, fmt, arg);
va_end(arg);
return r;
}
Опять же банальный пример, чтобы просто понять логику (например, с помощью vsnprintf можно легко запилить свою реализацию asprintf). В общем, я всё правильно делаю (кроме того что пытаюсь получить bool через va_arg).
В реальном коде у меня было что-то подобное (была обёртка вокруг функции, которая принимала va_list), однако для рассматриваемого бага это не имеет никакого значения. Да, func нельзя вызывать напрямую, а надо через обёртку, которой нет, но суть то в том, что код некорректный генерируется (а обёртка гипотетически может быть в другом файле, так что на кодогенерацию её отсутствие не должно влиять).
Исправление KivApple, :
Не-а. Где ты увидел у этой функции переменное число аргументов? va_start/va_end делает другая функция, которая имеет действительно переменное число аргументов.
Сейчас приведу простой пример:
int vprintf(const char *fmt, va_list arg) {
...
}
int printf(const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
int r = vprintf(fmt, arg);
va_end(arg);
return r;
}
Именно такая логика у функций printf/vprintf в libc (разумеется, я всё упростил для наглядности).
Функция с переменным числом аргументов часто является лишь обёрткой над функцией принимающей va_list. Зачем это нужно? Например, за этим:
int debug_printf(const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
fprintf(stderr, "DEBUG: ");
int r = vfprintf(stderr, fmt, arg);
va_end(arg);
return r;
}
Опять же банальный пример, чтобы просто понять логику. В общем, я всё правильно делаю (кроме того что пытаюсь получить bool через va_arg).
В реальном коде у меня было что-то подобное (была обёртка вокруг функции, которая принимала va_list), однако для рассматриваемого бага это не имеет никакого значения. Да, func нельзя вызывать напрямую, а надо через обёртку, которой нет, но суть то в том, что код некорректный генерируется (а обёртка гипотетически может быть в другом файле, так что на кодогенерацию её отсутствие не должно влиять).
Исправление KivApple, :
Не-а. Где ты увидел у этой функции переменное число аргументов? va_start/va_end делает другая функция, которая имеет действительно переменное число аргументов.
Сейчас приведу простой пример:
int vprintf(const char *fmt, va_list arg) {
...
}
int printf(const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
int r = vprintf(fmt, arg);
va_end(arg);
return r;
}
Именно такая логика у функций printf/vprintf в libc (разумеется, я всё упростил для наглядности).
Функция с переменным числом аргументов часто является лишь обёрткой над функцией принимающей va_arg. Зачем это нужно? Например, за этим:
int debug_printf(const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
fprintf(stderr, "DEBUG: ");
int r = vfprintf(stderr, fmt, arg);
va_end(arg);
return r;
}
Опять же банальный пример, чтобы просто понять логику. В общем, я всё правильно делаю (кроме того что пытаюсь получить bool через va_arg).
В реальном коде у меня было что-то подобное (была обёртка вокруг функции, которая принимала va_list), однако для рассматриваемого бага это не имеет никакого значения. Да, func нельзя вызывать напрямую, а надо через обёртку, которой нет, но суть то в том, что код некорректный генерируется (а обёртка гипотетически может быть в другом файле, так что на кодогенерацию её отсутствие не должно влиять).
Исходная версия KivApple, :
Не-а. Где ты увидел у этой функции переменное число аргументов? va_start/va_end делает другая функция, которая имеет действительно переменное число аргументов.
Сейчас приведу простой пример:
int vprintf(const char *fmt, va_list arg) {
...
}
int printf(const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
int r = vprintf(fmt, arg);
va_end(arg);
return r;
}
Именно такая логика у функций printf/vprintf в libc (разумеется, я всё упростил для наглядности).
Функция с переменным числом аргументов часто является лишь обёрткой над функцией принимающей va_arg. Зачем это нужно? Например, за этим:
int debug_printf(const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
fprintf(stderr, "DEBUG: ");
int r = vfprintf(stderr, fmt, arg);
va_end(arg);
return r;
}
Опять же банальный пример, чтобы просто понять логику. В общем, я всё правильно делаю (кроме того что пытаюсь получить bool через va_arg).