Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ GTK+ _ Неизвестный тип

Автор: ido 19.3.2011, 15:37

При подключении gdktypes.h из gtk+-2.2 в препроцессорном листинге есть строки

typedef __builtin_va_list __gnuc_va_list;
typedef __gnuc_va_list va_list;

У __builtin_va_list неизвестен базовый тип. В каком файле его можно найти?

P.S. gcc 4.1.1

Автор: ido 20.3.2011, 9:24

Поставлю вопрос по-другому.
В том же файле(после препроцессора) есть функции, например:

gint g_vsnprintf (gchar *string, gulong n, gchar const *format, va_list args);

gchar *g_markup_vprintf_escaped (const char *format, va_list args);

guint g_signal_new_valist (const gchar *signal_name, GType itype, GSignalFlags signal_flags, GClosure *class_closure, GSignalAccumulator accumulator, gpointer accu_data, GSignalCMarshaller c_marshaller, GType return_type, guint n_params, va_list args);

Как определить тип args?
Если это просто количество аргументов функции, тогда int.
Если что-то похожее на printf(), тогда структура какая-то…

Автор: Iron Bug 20.3.2011, 20:22

насколько мне известно, исходя из данных, в va_arg/va_list тип определить невозможно. тип должен определяться как-то извне. в printf и т.п. для этого парcится строка с форматом. если формат не совпадает - возникает ошибка обращения к памяти.

Автор: ido 21.3.2011, 8:22

Цитата(Iron Bug @ 20.3.2011, 20:22) *
в printf и т.п. для этого парcится строка с форматом.
Т.е парсится во время компиляции каким-то макросом, размещается в некой структуре по каким-то правилам? Тогда в исходниках(gcc) должна быть последовательность выполняемых операций.

В ChangeLog’e gcc-2.95 есть единственное упоминание:

ginclude/varargs.h(va_dcl):
Use word_mode for type of __builtin_va_list

В gcc-3.3 много, где используется. Используется, но не определяется. Вот, пример из c-common.c:

(* lang_hooks.decls.pushdecl)
(build_decl (TYPE_DECL, get_identifier("__builtin_va_list"), ptrdiff_type_node));

Но, что бы это значило…


Автор: Iron Bug 21.3.2011, 13:59

Цитата(ido @ 21.3.2011, 10:22) *
Т.е парсится во время компиляции каким-то макросом

нет. парсится в риалтайме, как стандартно парсятся переменные параметры, передаваемые через стек (va_arg и иже с ним). компилятор не делает никаких проверок насчёт содержимого va_arg. потому что он просто не может их делать. в общем, это обычные функции с переменным числом параметров. выкопать типы в условиях переменного количества параметров просто нереально. RTTI не передаётся явно. если очень хочется, можно сделать иерархию классов, передавать указатель на базовый класс и проверять typeid внутри самой функции.

Автор: ido 21.3.2011, 16:05

Вот, нашел программку http://invisible-island.net/cproto/. Она генерит прототипы C-функций и конвертирует их определения. В CHANGES записано

Цитата
- add gcc-specific __builtin_va_list keyword.

Теперь, во-первых, непонятно как ей передать параметры обычные для компиляции gtk+ (pkg-config…). Пытался тупо подставлять __builtin_va_list в пример – ничего не меняется, хотя из самого примера с main() прототип получается.

Автор: Iron Bug 21.3.2011, 23:02

ты, собственно, чего хочешь добиться от компилятора?
методы использования va_arg/va_list задокументированы в доках по С++. они не менялись, определения RTTI типов там нет, не было и не будет. используются они с заранее известными типами аргументов, либо информацию о типах в функцию передаёт сам программист, как ему удобнее.

Автор: ido 23.3.2011, 6:39

От компилятора ничего :) Нужно __builtin_va_list собрать из базовах типов. Я с этого начал :)

Про С++(RTTI) -- это новость. Ведь gtk+ написан на простом си. Насколько я знаю va_arg – это макрос

type va_arg(va_list argptr, type);

Автор: Iron Bug 23.3.2011, 7:28

макросы макросами, но ни с C++, ни в C у va_list нет никакого "определения". это не тип вообще. это просто метод передачи параметров через стек, и только. и он зависит от платформы и от компилятора. это просто указание компилятору, что нужно засунуть в стек параметры, а потом извлечь их и передать юзеру. если хочешь знать, как это конкретно реализовано в конкретном компиляторе - читай сорцы компилятора.

Автор: ido 23.3.2011, 9:29

Вот, нашел в cygwin/mingw.

 #ifndef    _VA_LIST
#define _VA_LIST
#if defined __GNUC__ && __GNUC__ >= 3
typedef __builtin_va_list va_list;
#else
typedef [b]char*[/b] va_list;
#endif
#endif

К плюсам имеют отношение, скорее всего,
__attribute__
__extension__
__const
__restrict

Например
gchar* g_strdup_vprintf (const gchar *format, va_list args) __attribute__((__malloc__)) ;

Но как это обрабатывается – найти в сорцах и не получается.

Автор: ido 23.3.2011, 20:27

Всё кажется понял.
Например, есть функция

 va_start (args, message_format);
      msg = g_strdup_vprintf (message_format, args);
      va_end (args);

Макросы va_start/va_end – поддержка рантайма. Они прогоняют аргументы функции через стэк.
 #define va_arg(v,l)    __builtin_va_arg(v,l)

 /* varargs.h. */
#ifndef __va_list__
#define __va_list__
typedef char *va_list;
#endif
#define va_dcl int va_alist;
#define va_start(list) list = (char *) &va_alist
#define va_end(list)
#define va_arg(list,mode) ((mode *)(list += sizeof(mode)))[-1]

Только __builtin_va_arg теряется где-то в парсерах/лексерах.

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)