Форум: "Потрепаться";
Текущий архив: 2004.10.03;
Скачать: [xml.tar.bz2];
ВнизЗадача знатокам С++ Найти похожие ветки
← →
Igorek © (2004-09-09 17:23) [0]Написать ф-цию
void f1(int x...) { f2(???); },
которая вызывала бы
void f2(int x...) {}
и передавала все свои аргументы ей.
← →
вразлет © (2004-09-09 17:25) [1]и в чем проблема?
← →
wicked © (2004-09-09 18:01) [2]хы-хы... говорим f1, подразумеваем f2?...
#define f1 f2
:)
← →
Igorek © (2004-09-09 19:11) [3]
> вразлет © (09.09.04 17:25) [1]
> и в чем проблема?
У кого?
> wicked © (09.09.04 18:01) [2]
> хы-хы... говорим f1, подразумеваем f2?...
> #define f1 f2
Условие читаем? :-)
← →
wicked © (2004-09-09 19:33) [4]> Igorek [3]
задача решена?... нигде же не сказано, что можно использовать, а что - нет... :)
а если "по правильному", то задачу без какого-либо препроцессора или егенратора не решить... разве что ввести ограничения на тип и количество аргументов и передавать отдельным аргументом число оставшихся аргументов...
← →
wl (2004-09-09 20:10) [5]
f2(int x) { return x;}
f1(int x) { f2(x); return 0;}
пойдёт такое решение?
← →
wl (2004-09-09 20:11) [6]ааа, возвращают void... значит без return-ов...
← →
Igorek © (2004-09-09 20:45) [7]
> wicked © (09.09.04 19:33) [4]
> > Igorek [3]
> задача решена?... нигде же не сказано, что можно использовать,
> а что - нет... :)
Сказано
> Написать ф-цию
> void f1(int x...) { f2(???); },
А что будет, если поставишь #define f1 f2 ? Зацикливание рекурсией или "ф-ция уже определена".
> а если "по правильному", то задачу без какого-либо препроцессора
> или егенратора не решить...
Вот меня это тоже интересует.
> wl (09.09.04 20:10) [5]
> f2(int x) { return x;}
> f1(int x) { f2(x); return 0;}
> пойдёт такое решение?
Неа. При вызове f1(1,2) - второй параметр не передастся в f2.
← →
VMcL © (2004-09-09 21:37) [8]>>Igorek © (09.09.04 17:23)
Написать ф-цию
void f1(int x...) { f2(???); },
которая вызывала бы
void f2(int x...) {}
и передавала все свои аргументы ей.void f2(...)
{
}
#define f1 f2
← →
Verg © (2004-09-09 21:45) [9]Бред какой-то.
Ты чего, на va_list (va_start, va_arg...) тянешь?
Что блин за задачки с тремя неизвестными, половина из которых у тебя в уме соталась?
← →
wicked © (2004-09-09 22:03) [10]не тянет, поскольку не сказано, что есть один фиксированный параметр... тем более, что va_list как раз и требует один фиксированный параметр, от которого он отталкивается....
← →
Verg © (2004-09-09 22:41) [11]
> не тянет, поскольку не сказано, что есть один фиксированный
> параметр...
> Написать ф-цию
> void f1(int x...) { f2(???); },
> которая вызывала бы
> void f2(int x...) {}
> и передавала все свои аргументы ей.
? :))
← →
вразлет © (2004-09-10 09:17) [12]Афтар, а что такое "знатоки С++" ?
← →
Igorek © (2004-09-10 10:36) [13]
> VMcL © (09.09.04 21:37) [8]
> void f2(...)
> {
> }
> #define f1 f2
Прошу прощения, а где собственно f1?
Люди, я не прошу просто сделать возможным вызов в виде f1(...). Мне нужно реальное тело функции, которая вызывается.
> Verg © (09.09.04 21:45) [9]
> Бред какой-то.
> Ты чего, на va_list (va_start, va_arg...) тянешь?
> Что блин за задачки с тремя неизвестными, половина из которых
> у тебя в уме соталась?
Фиксированый параметр для va_start есть. Необязательные параметры и их колл. вам и знать не надо - это знает только создатель f2.
Все что надо - известно.
> wicked © (09.09.04 22:03) [10]
> не тянет, поскольку не сказано, что есть один фиксированный
> параметр
Ну как не сказано? А f1(int x...) - это что такое?
← →
VMcL © (2004-09-10 13:09) [14]>>Igorek © (10.09.04 10:36) [13]
>Люди, я не прошу просто сделать возможным вызов в виде f1(...). Мне нужно реальное тело функции, которая вызывается.
Можно и гланды через задний проход удалять. Но вот только зачем?
← →
GuAV © (2004-09-10 21:07) [15]Igorek © (10.09.04 10:36) [13]
Вот,
> через задний проходprocedure F1(X, Y, Z: Integer);
begin
ShowMessageFmt("X=%D Y=%D Z=%D",[X,Y,Z]);
end;
procedure FF2; // Параметров не знаем
asm
// Реальное тело F2
PUSH OFFSET F1
end;
type
TF1 = procedure(X, Y, Z: Integer);
var
PF2: pointer = @FF2;
F2: TF1 absolute PF2;
← →
Verg © (2004-09-10 21:33) [16]
> Фиксированый параметр для va_start есть. Необязательные
> параметры и их колл. вам и знать не надо - это знает только
> создатель f2.
> Все что надо - известно.
Так ты о чем же собственно?
Умных слов-загадок потолкать или что? :))
← →
DiamondShark © (2004-09-11 11:01) [17]Внутри функции невозможно узнать количество переданных параметров, функция об этом должна догадываться какими-то шаманскими методами (например, интерпретируя значение фиксированных параметров, но точное угадывание никто не гарантирует).
Поэтому решение может быть примерно такое: погадать по звёздам о длине переданных параметров, ассемблерной вставкой переписать их в стек и вызвать функцию.
← →
Артем Запаранюк © (2004-09-11 17:56) [18]Мой вариант.
int array[]={10,8,6,4,2,0};
void f2(int x, int [])
{
//тело функции, где выполняются операции над переменными
}
void f1(int x, int ara[])
{
f2 (x, ara);
}
//Вызываем функцию ф1
f1(5,array);
Смысл в том что, х-указывает число переменных в массиве, который передается с помощью второй переменной.
Массив содержит переменные, которые нужно обработать.
Такой подход реализован, например, в функции WinMain (см. help по С++).
← →
Igorek © (2004-09-12 15:19) [19]
> VMcL © (10.09.04 13:09) [14]
> Можно и гланды через задний проход удалять. Но вот только
> зачем?
Неудачное сравнение. Здесь нельзя сделать не через з/п в отличии от гланд.
А зачем? Ну во-первых чисто академический интерес. Во-вторых возникла реальная задача такого плана.
> GuAV © (10.09.04 21:07) [15]
Это не С++.
> Verg © (10.09.04 21:33) [16]
> > Фиксированый параметр для va_start есть. Необязательные
> > параметры и их колл. вам и знать не надо - это знает только
> > создатель f2.
> > Все что надо - известно.
> Так ты о чем же собственно?
> Умных слов-загадок потолкать или что? :))
Не понял, что ты конкретно не понял. :)
> DiamondShark © (11.09.04 11:01) [17]
> Внутри функции невозможно узнать количество переданных параметров,
> функция об этом должна догадываться какими-то шаманскими
> методами (например, интерпретируя значение фиксированных
> параметров, но точное угадывание никто не гарантирует).
А нам и не нужно знать колл. параметров. Мы ж их не юзаем. Просто передает. Все что надо - знать их сумарный размер.
> Поэтому решение может быть примерно такое: погадать по звёздам
> о длине переданных параметров, ассемблерной вставкой переписать их в стек и вызвать функцию.
Вот-вот. Подозреваю единственное решение - копирование стека. Но как его сделать?
> Артем Запаранюк © (11.09.04 17:56) [18]
Мы не знаем не только колл. но и типы параметров.
---
У ф-ций стандартной библиотеки ввода-вывода есть ф-ции ...printf и соотв. им эквиваленты v...printf, которые принимают явный список параметров va_list. Если бы был простой способ передачи, то их бы просто не было.
---
Сдается мне что нашел таки первые грабли С++ :-(
← →
wicked © (2004-09-12 17:51) [20]> Igorek © (12.09.04 15:19) [19]
> У ф-ций стандартной библиотеки ввода-вывода есть ф-ции ...printf
> и соотв. им эквиваленты v...printf, которые принимают явный
> список параметров va_list. Если бы был простой способ передачи,
> то их бы просто не было.
ну так как раз они по первому параметру и гадают, что там дальше на стеке... и если в параметры засунуть структуру (по значению), то то, что попадет в подстановку, и будет воспринято, как нормальное значение....
> Сдается мне что нашел таки первые грабли С++ :-(
сори, но зачем перекладывать с больной головы на здоровую?...
эти, так сказать, грабли присущи будут всем языкам со строгой типизацией аргументов...
то, что это хоть как-то реализовано в делфи - это скорее заслуга жутко развитой RTTI, а не недостаток си++ (или си, или простого паскаля, или хз чего еще)...
хотя в перле такая фича есть... ;)
← →
wicked © (2004-09-12 18:08) [21]гых... раз уж речь зашла о printf"ах, то могу порекомендовать такие прототипы функций:
1.void f1(char * mask, ...);
делает всё что необходимо делать порядочной функции по имени f1, затем формирует va_list на свои переменные аргументы и передает управление ф-ции real_f2....
2.void f2(char * mask, ...);
просто формирует va_list на свои переменные аргументы и передает управление ф-ции real_f2....
3.void real_f2(char * mask, va_list arglist);
делает всё, что должна была делать ф-ция f2....
теперь перейдем к мистическому параметру mask... в него мы должны передать строку, каждый символ которой будет говорить функции о типа параметра, а позиция сего символа в строке - о порядковом номере аргумента... например:int i, j;
double c, d;
char * string;
... // какой нибудь код....
f1("sidid", string, i, d, j, c);
... // еще какой нибудь код....
f1("ddii", c, d, j, i);
надеюсь, идея ясна?...
ЗЫ а вообще то, такие вещи не решаются чисто языковыми средствами, даже если уж так приспичило...
← →
Igorek © (2004-09-12 19:07) [22]> wicked © (12.09.04 17:51) [20]
> сори, но зачем перекладывать с больной головы на здоровую?...
> эти, так сказать, грабли присущи будут всем языкам со строгой
> типизацией аргументов...
При чем тут строгая типизация? И чем поможет нестрогая? Приведи пример языка с нестрогой типизацией, переменным колличеством аргументов ф-ции и реши на нем поставленную задачу.
Массивы вариантов - не в счет. :-)
> то, что это хоть как-то реализовано в делфи
А как это реализовано в Дельфи? Насколько я знаю вообще не реализовано. :)
> надеюсь, идея ясна?...
Понятно, но в сабже задача общего плана. А пример с printf я привел как непрямой довод о невозможности решения.
В задаче сказано
> Написать ф-цию
> void f1(int x...) { f2(???); },
> которая вызывала бы
> void f2(int x...) {}
> и передавала все свои аргументы ей.
Т.е.
1) сигнатуры полностью совпадают
2) есть переменное колл. аргументов
Хорошо конечно что в языке С++ есть переменное колл. аргументов. И понятно, что ф-ция, которая их принимает должна сама вырулить сколько их и каковы типы.
Но почему нельзя в общем случае все это передать другой ф-ции - непонятно.
Имхо - грабли.
← →
DiamondShark © (2004-09-12 19:52) [23]
> А нам и не нужно знать колл. параметров. Мы ж их не юзаем.
> Просто передает. Все что надо - знать их сумарный размер.
А без разницы. Всё равно ни того ни другого не известно.
> > Поэтому решение может быть примерно такое: погадать по
> звёздам
> > о длине переданных параметров, ассемблерной вставкой переписать
> их в стек и вызвать функцию.
>
> Вот-вот. Подозреваю единственное решение - копирование стека.
> Но как его сделать?
Ну, если размер выяснить удалось, то уже просто: они находятся сплошным блоком начиная с фиксированного параметра.
> Но почему нельзя в общем случае все это передать другой
> ф-ции - непонятно.
> Имхо - грабли.
Ц и есть одни сплошные грабли.
← →
Verg © (2004-09-12 20:03) [24]
> Ц и есть одни сплошные грабли.
Программирование вообще - то ли для тех, кто не боится граблей, то ли для тех, кому всевозможные грабли - здоровый спорт.
А кому-то и кружку чая себе приготовить - грабли, дойти до сортира - один сполшной глюкодром, а смыть за собой - полный масдай.
← →
DiamondShark © (2004-09-12 20:12) [25]
> Программирование вообще - то ли для тех, кто не боится граблей,
> то ли для тех, кому всевозможные грабли - здоровый спорт.
Угу. А те, кто с граблями предпочитает не связываться, и не програмисты вовсе, а так... погулять вышли.
← →
Igorek © (2004-09-12 20:53) [26]> DiamondShark © (12.09.04 19:52) [23]
> > А нам и не нужно знать колл. параметров. Мы ж их не юзаем.
> > Просто передает. Все что надо - знать их сумарный размер.
> А без разницы. Всё равно ни того ни другого не известно.
Не без разницы. Компилятор знает смещение и размер. По моему логично было бы позволить вызов вида f2(x, ...).
Т.е. "..." можно рассматривать как лексический элемент, указывающий на произвольное колл. параметров, и не определенный в теле функции с сигнатурой без "...".
> Ну, если размер выяснить удалось, то уже просто: они находятся сплошным блоком начиная с фиксированного параметра.
В общем случае мы не знаем размер. В отличии от компилятора.
> Ц и есть одни сплошные грабли.
Мягко говоря не согласен.
> Verg © (12.09.04 20:03) [24]
> DiamondShark © (12.09.04 20:12) [25]
Хорош демагогить! :-)
Больше конкретики.
← →
DiamondShark © (2004-09-12 21:20) [27]
> Не без разницы. Компилятор знает смещение и размер. По моему
> логично было бы позволить вызов вида f2(x, ...).
В том-то и дело, что не знает. Функцией с переменным числом параметров может быть только функция cdecl, т.е. управлением стеком занимается вызывающий код. В точке вызова известно число и размеры (типы) параметров, в функции -- нет.
> В общем случае мы не знаем размер. В отличии от компилятора.
Компилятор его тоже не знает.
В точке вызова знает, внутри функции -- нет.
Компилятор эту информацию мог бы знать, если бы, скажем, в функцию передавались -- как скрытые параметры -- число или длина параметров. Но эта информация не передаётся.
← →
Verg © (2004-09-12 21:29) [28]
> [26] Igorek © (12.09.04 20:53)
С каких пирогов ты на своем трепе хочешь конкретики. Какой?
Ты что-то имеешь предложить или, ... ?
> Не без разницы. Компилятор знает смещение и размер. По моему
> логично было бы позволить вызов вида f2(x, ...).
> Т.е. "..." можно рассматривать как лексический элемент,
> указывающий на произвольное колл. параметров, и не определенный
> в теле функции с сигнатурой без "...".
Хорошь пустомелить! :-()
← →
wicked © (2004-09-12 22:13) [29]> Igorek [22]
> Т.е.
> 1) сигнатуры полностью совпадают
> 2) есть переменное колл. аргументов
я дико извиняюсь, но чем не угодили сигнатуры в [21]:
> 1. void f1(char * mask, ...);
> 2. void f2(char * mask, ...);
как видим, они идентичны, а то, что эти функции делают "под водой", это их личные заботы....
> Но почему нельзя в общем случае все это передать другой
> ф-ции - непонятно.
можно - va_list...
если по-си++"ному (по-модному) - реализовать в классе COM-интерфейс IDispatch и передавать всё через аргументы Invoke... такой себе VBA в миниатюре... ;)
> Приведи пример языка с нестрогой типизацией, переменным
> колличеством аргументов ф-ции и реши на нем поставленную
> задачу.
повторю еще раз - PERL...
> Понятно, но в сабже задача общего плана. А пример с printf
> я привел как непрямой довод о невозможности решения.
возможно... но Анголообразные языки в общем то разрабатывались без нацела на фичи, которые вдруг когда-то кому-то понадобятся - если язык не предоставляет какого-либо механизма, то этот механизм можно реализовать, как библиотеку....
а если хочется умного компилятора, то советую приглядеться к Lisp"у и/или Prolog"у...
> Verg [24]
хы-хы.... :)
← →
wicked © (2004-09-12 22:15) [30]блин....
> wicked [29]
Анголообразные = Алголообразные...
← →
False_Delirium © (2004-09-12 23:15) [31]wicked [29]
Чтобы Perl затрагивать нужно знать как он хранит данные, к какому типу приводит все переменные. А потом уже ставить его в пример. Он только благодаря своему механизму позволяет передавать в ф-ции переменное кол-во параметров.
И в конечном этоге Perl - это "обкрутка" механизмов С. Если уж так говорить, то нужно ставить вопрос о разработке интерпритируемой системы, которая позволяла бы передавать своим ф-циям переменное кол-во параметров.
← →
wicked © (2004-09-12 23:22) [32]> False_Delirium [31]
перл я видел издалека... спасибо за науку... :)
← →
Igorek © (2004-09-13 11:48) [33]> Verg © (12.09.04 21:29) [28]
> > [26] Igorek © (12.09.04 20:53)
> С каких пирогов ты на своем трепе хочешь конкретики.
> Хорошь пустомелить! :-()
Тебе наверно за последнее мастера дали.
> DiamondShark © (12.09.04 21:20) [27]
> Компилятор его тоже не знает.
> В точке вызова знает, внутри функции -- нет.
Тут ты прав. Но мы углубились в тонкости реализации компилятора. Хотя можно придумать выход из ситуации. Я стараюсь проанализировать (...) с высокоуровневой точки зрения.
> wicked © (12.09.04 22:13) [29]
Я прошу прощения, но вы невнимательно читаете мои посты.
---
Перечитал вчера еще раз соотв. главу Страуструпа. Там тоже эта ситуация не упоминается. Насчет (...) сказано, что надо их избегать, реальных ситуаций, в которых они могут потребоваться - мало и вообще они введены для совместимости с С.
← →
Игорь Шевченко © (2004-09-13 11:53) [34]Между прочим, printf и ей подобные считают количество нужных аргументов исключительно по строке формата...Можно передать в printf много аргументов, если в строке формата ссылок на них не будет, то printf ничего про них не узнает.
va_list - всего лишь адрес аргумента в стеке.
← →
DiamondShark © (2004-09-13 13:35) [35]
> Но мы углубились в тонкости реализации компилятора. Хотя
> можно придумать выход из ситуации. Я стараюсь проанализировать
> (...) с высокоуровневой точки зрения.
С высокоуровневой точки зрения, средства доступа к параметрам должны быть частью языка. Макросы va_list, va_arg, etc -- средства внеязыковые, и основаны именно на тонкостях реализации компилятора.
← →
Странник © (2004-09-13 13:49) [36]нечто подобное реализовано в Clipper"е, но с ограничениями.
← →
DiamondShark © (2004-09-13 13:54) [37]
> если в строке формата ссылок на них не будет, то printf
> ничего про них не узнает.
Гораздо интереснее, если в строке формата они есть, а вот переданы не будут.
← →
Игорь Шевченко © (2004-09-13 13:59) [38]DiamondShark © (13.09.04 13:54) [37]
> Гораздо интереснее, если в строке формата они есть, а вот
> переданы не будут.
При этом в большинстве случаев будет либо Access Violation, если указан строковый спецификатор формата, либо случайные числа, если указаны числовые спецификаторы формата.
Я свой пример с printf привел к тому, что вызываемой функции необходимо каким-то образом сообщать, сколько же параметров ей надо принимать во внимание :)
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.10.03;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.148 c