The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Интерфейс printf"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Интерфейс printf"  
Сообщение от ghost_in_machine email on 17-Янв-06, 19:42 
Здравствуйте!
Хочу спросить у знающих людей о передаче параметров в функции на C. Вот есть очень удобный интерфейс у семейства функций printf(char *,...) но я нигде не могу найти как эти три точки принимает функция и преобразует в адреса переменных.
Спасибо большое.
Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Сообщения по теме [Сортировка по времени, UBB]


2. "Интерфейс printf"  
Сообщение от veslo (ok) on 17-Янв-06, 23:42 
man va_arg
Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "Интерфейс printf"  
Сообщение от ghost_in_machine email on 18-Янв-06, 13:58 
Спасибо, veslo.
Посмотрел я man и не сильно проникся. Есть ли какой-нибудь другой способ передать в функцию произвольный набор параметров без указаний их типов? Можно конечно каждый раз выделять память под структуру а-ля листа и складывать все адреса туда, но, может, есть способ решить проблему уже на этапе компиляции (компилятор то знает сколько параметров передают в конкретном вызове функции).
Спасибо.

Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "Интерфейс printf"  
Сообщение от Аноним on 18-Янв-06, 16:28 
>Есть ли какой-нибудь другой способ передать в функцию произвольный набор параметров без указаний их типов?

Есть, но не в C.
Вобщем используй va_arg, там ничего страшного.

Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "Интерфейс printf"  
Сообщение от Brick email(??) on 19-Янв-06, 01:09 
>компилятор то знает сколько параметров передают в конкретном вызове  

компилятор С ничего не знает про количество аргументов, переданных функции

Почитать про этот механизм можно здесь:
http://www.citforum.ru/security/articles/printf/
http://www.intuit.ru/department/pl/c/9/4.html

Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "Интерфейс printf"  
Сообщение от Forth (??) on 19-Янв-06, 09:09 
>компилятор С ничего не знает про количество аргументов, переданных функции
Почему? Знает. Иначе не смог бы отчистить стек по выходу из функции.


Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "Интерфейс printf"  
Сообщение от tilde on 19-Янв-06, 09:26 
>>компилятор С ничего не знает про количество аргументов, переданных функции
>Почему? Знает. Иначе не смог бы отчистить стек по выходу из функции.
>

Не знает. Стек очищает вызывающая функция. Поэтому вызванная функция может даже не знать общий размер всех параметров.

Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "Интерфейс printf"  
Сообщение от Forth (??) on 19-Янв-06, 09:39 
>Не знает. Стек очищает вызывающая функция. Поэтому вызванная функция может даже не
>знать общий размер всех параметров.
Ну да, вызывающая функция. А кто как не компилятор помещает в неё инструкцию отчистки стека? Я что-то не понимаю как может компилятор не знать про количество параметров, при том что он же помещение этих параметров в стек и компилирует. И потом после вызова функции вставляет очистку стека.
Я думаю Вы что-то другое имели в виду.

Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "Интерфейс printf"  
Сообщение от ACCA (ok) on 19-Янв-06, 12:05 
>>Не знает. Стек очищает вызывающая функция. Поэтому вызванная функция может даже не
>>знать общий размер всех параметров.
>Ну да, вызывающая функция. А кто как не компилятор помещает в неё
>инструкцию отчистки стека? Я что-то не понимаю как может компилятор не

Принимать произвольное число аргументов - свойство вызываемой функции, а не вызывающей. Компилятор ещё ничего не знает про вызывающую.

Переменное число аргументов в современном C (C89 и новее) положено обрабатывать только с помощью stdarg, varagrs типа маст дай.

Потрать полчаса на изучение - там ничего сложного.

Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

10. "Интерфейс printf"  
Сообщение от Forth (??) on 19-Янв-06, 12:31 
> "компилятор С ничего не знает про количество аргументов, переданных
> функции"
Видимо имелось в виду "компилятор С _внутри вызываемой функции_ ничего не знает про количество аргументов, переданных этой функции" , а я подумал почему-то про вызывающую.:confuse:


Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

11. "Интерфейс printf"  
Сообщение от ghost_in_machine email on 19-Янв-06, 12:57 
Спасибо всем за инфу. У меня возник вопрос по стеку. Если узнать адрес конца стека то функция типа f(int num,void** stack) будет именно тем что нужно. А можно ли в С узнать адрес стека? Будет ли это &num в принимающей функции?
Спасибо.

Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

12. "Интерфейс printf"  
Сообщение от ghost_in_machine email on 19-Янв-06, 13:00 
>Спасибо всем за инфу. У меня возник вопрос по стеку. Если узнать
>адрес конца стека то функция типа f(int num,void** stack) будет именно
>тем что нужно. А можно ли в С узнать адрес стека?
>Будет ли это &num в принимающей функции?
>Спасибо.
Sorry должно быть f(int num,...)

Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

13. "Интерфейс printf"  
Сообщение от Brick email(??) on 19-Янв-06, 14:39 
>>Спасибо всем за инфу. У меня возник вопрос по стеку. Если узнать
>>адрес конца стека то функция типа f(int num,void** stack) будет именно
>>тем что нужно. А можно ли в С узнать адрес стека?
>>Будет ли это &num в принимающей функции?
>>Спасибо.
>Sorry должно быть f(int num,...)
да, именно, &num и будет адресом начала стека, а вот с концом, там уже самому надо выдумывать, почитай, я выше давал ссылки,там описывается этот механизм, а вообще, выше писали, для этого есть стандартные решения
Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

14. "Интерфейс printf"  
Сообщение от ghost_in_machine email on 19-Янв-06, 15:29 
Спасибо Brick. Стандартные решения выглядят более запутанными. Я только немного не понял, возможен ли вариант каких-то пробелов между объектами из одного вызова или гарантированно они будут идти друг за другом согласно своим размерам. В ваших ссылках была пара туманных слов о запутанности структуры стека при работе современных компиляторов...
Спасибо.  


Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

15. "Интерфейс printf"  
Сообщение от Brick email(??) on 19-Янв-06, 15:51 
аргументы в стеке будут идти подряд, один за одним а для разбора параметров существует два класических приема:

1) Все аргументы должны быть одного и того же типа и используется какой-нибудь маркер конца списка аргументов, например, f1("arg1", "arg2", ... , "argN", "NULL"), где NULL и будет маркером конца аргументов.

2) Первый, обязательный аргумент может содержать либо количество принимаемых функцией аргументов, если они одного и того же типа, либо, как это используется в семействе функций printf форматная строка, на основе которой ты разбираешь все аргументы, т.е. их типы и количество.

Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

16. "Интерфейс printf"  
Сообщение от ghost_in_machine email on 19-Янв-06, 16:07 
А что произойдет со стеком (его конкретным участком, содержащим параметры), если я вызову другую функцию внутри обработчика стека? Будут ли адреса стека и его элементов все еще валидными? И еще, как мне передать адрес стека в другую функцию, через void* или есть вариант для "три точки" -> "три точки" напрямую?
Спасибо.


Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

17. "Интерфейс printf"  
Сообщение от Brick email(??) on 19-Янв-06, 16:41 
>А что произойдет со стеком (его конкретным участком, содержащим параметры), если я вызову другую функцию внутри обработчика стека? Будут ли адреса стека и его элементов все еще валидными?
с адресами юудет вс
Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

18. "Интерфейс printf"  
Сообщение от Brick email(??) on 19-Янв-06, 16:48 
>А что произойдет со стеком (его конкретным участком, содержащим параметры), если я вызову другую функцию внутри обработчика стека? Будут ли адреса стека и его элементов все еще валидными?
что касается адресов, то всё будет нормально, эти аргументы ничем не отличаются от обычных аргументов функции

>И еще, как мне передать адрес стека в другую функцию, через void* или есть вариант для "три точки" -> "три точки" напрямую?
да, через stdarg: http://www.opennet.ru/docs/RUS/glibc/glibc-7.html

Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

19. "Интерфейс printf"  
Сообщение от ghost_in_machine email on 19-Янв-06, 17:00 
Спасибо всем (и Brick особенно), теперь понятно.
Всем успехов!
Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ]




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2021 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру