LINUX.ORG.RU

История изменений

Исправление 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).