Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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.044 c
8-1089102438
Urvin
2004-07-06 12:27
2004.10.03
КАК уменьшить количество цветов в картинке


9-1083579189
OSokin
2004-05-03 14:13
2004.10.03
Максимально возможная игра


8-1089106744
REA
2004-07-06 13:39
2004.10.03
Big Bitmap


14-1095071269
Holy
2004-09-13 14:27
2004.10.03
Mad Max. Кажется была такая команда...


1-1095283565
KilkennyCat
2004-09-16 01:26
2004.10.03
интерфейс как у Delphi.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский