Вызов процедуры с неверным количеством параметров

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

xdsl
постоялец
Сообщения: 131
Зарегистрирован: 15.01.2009 12:49:03

Вызов процедуры с неверным количеством параметров

Сообщение xdsl »

Идея: вызывать процедуру с большим кол-м параметров, чем было для нее заявлено. Причины делать именно так есть, другие варианты не подходят.
Приведенный ниже пример работает как надо.
Вопрос к тем, кто понимает устройство компилятора: как это может аукнуться? Не появятся-ли утечки памяти, не рухнет-ли в самый неожиданный момент программа и т.п.?

Код: Выделить всё

procedure x(a:integer;b:real);
begin
 writeln(a,b:5:2);
end;

type tx=procedure(a:integer; b:real; c:byte; d: boolean; e:ansistring);

begin
 tx(@x)(1,2.3,4,true,'hello');
end.
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

Зависит от соглашений о вызове. ничего хорошего не ждите

Добавлено спустя 2 минуты 12 секунд:
И вообще, какой смысл в этом? есть безопасные способы для переменного числа параметроа
Аватара пользователя
serbod
постоялец
Сообщения: 449
Зарегистрирован: 16.09.2016 10:03:02
Откуда: Минск
Контактная информация:

Сообщение serbod »

Компилятор не даст совершить такую фигню. Для таких случаев есть https://www.freepascal.org/docs-html/ref/refsu69.html
xdsl
постоялец
Сообщения: 131
Зарегистрирован: 15.01.2009 12:49:03

Сообщение xdsl »

serbod писал(а):Компилятор не даст совершить такую фигню.

Под линуксом компилятор даёт совершить такую фигню. А так как моя программа выполняется на микроконтроллере с дебианом на борту, другие операционки меня не волнуют.
Но не зная внутренней кухни, можно будет потом сесть в лужу при, например, смене версии компилятора. Поэтому и прошу совета у специалистов по компилятору Free Pascal

serbod писал(а):Для таких случаев есть https://www.freepascal.org/docs-html/ref/refsu69.html

Вариант с константным массивом у меня уже давно реализован, но это менее удобно, чем прямой доступ к параметрам. Поэтому ищу альтернативу.
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

А почему в procedure x(a:integer;b:real); не обявить все параметры и неиспользовать их? если это не ваша процедура, запускть ее через прокладку с объявлеными всеми параметрами
>>Поэтому ищу альтернативу.
Это не альтернатива совсем, вы только уменьшаете кол-во параметров и не меняете их тип. Т.е. делаете какуюто граблю на ровном месте.

>>Но не зная внутренней кухни, можно будет потом сесть в лужу при, например, смене версии компилятора.
Внутренняя кухня в обозримом будущем не поменяется. Но такой подход чреват другим - усложнение поддержки - сядете в лужу при внесении казалось бы безобидных изменений в свои исходники
Аватара пользователя
runewalsh
энтузиаст
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Сообщение runewalsh »

Так делать нельзя, никогда, работает по чистой случайности.
/thread
Аватара пользователя
alexs
долгожитель
Сообщения: 4066
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

как решение - объявить процедуру с максимальным кол-во параметров
а с меньшим объявлять через inline - по факту это будет равнозначно объявлению параметров с дефлотными значениями. Но плюс этого метода - в заинлайненных объявлениях можно менять порядок следования параметров.
Аватара пользователя
serbod
постоялец
Сообщения: 449
Зарегистрирован: 16.09.2016 10:03:02
Откуда: Минск
Контактная информация:

Сообщение serbod »

xdsl писал(а):Вариант с константным массивом у меня уже давно реализован, но это менее удобно, чем прямой доступ к параметрам. Поэтому ищу альтернативу.

Подумайте получше, что важнее - удобно при разработке или надежно при эксплуатации. Потратить минуты при разработке сейчас или потратить часы при отладке потом. Не исключаю, что у вас сугубо одноразовый демонстрационный проект, вроде тестового задания, где важнее сделать быстро, чем качественно.
xdsl
постоялец
Сообщения: 131
Зарегистрирован: 15.01.2009 12:49:03

Сообщение xdsl »

zub писал(а):А почему в procedure x(a:integer;b:real); не обявить все параметры и неиспользовать их? если это не ваша процедура, запускать ее через прокладку с объявлеными всеми параметрами

Потому-что процедуру объявляет конечный пользователь моего проекта, а я ее только вызываю. Говорить юзеру "Объяви процедуру со 100500 параметрами, потомучто" - не есть правильно. И я не знаю, сколько конкретно параметров объявит юзер. Поэтому максимум что я фиксирую, это устанавливаю верхнюю границу кол-ва параметров и требую для них всех тип variant. Либо только один параметр в виде константного массива (с этим вопросов нет, все работает штатно). После чего юзер передет мне указатель на эту процедуру.

Когда приходит время вызывать юзеровскую процедуру, то вызываю ее с максимальным кол-м аргументов, вне зависимости, сколько аргументов в ней было заявлено. И, блин, это работает! Я не верил в это, когда проверял, ждал проблем со стеком, сегфолта или утечек памяти, но работает все без проблем, debian 8,9, altlinux 7,8, fpc 2.6.4. 3.0.0, 3.0.2.

Вопрос только в одном: не эксплуатирую-ли я некий редкий баг, который с успехом и фанфарами исправят в новой версии fpc, поломав мне весь код?

serbod писал(а):Подумайте получше, что важнее - удобно при разработке или надежно при эксплуатации. Потратить минуты при разработке сейчас или потратить часы при отладке потом. Не исключаю, что у вас сугубо одноразовый демонстрационный проект, вроде тестового задания, где важнее сделать быстро, чем качественно.

О надежности и думаю, поэтому и поднял тут тему. И в релиз проекта эту фичу не запущу, пока не найду подтверждения, что это безопасно. Либо не найду и тогда откачу до предыдущей, крайне многословной версии. Хоть и не хочется.
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Вопрос только в одном: не эксплуатирую-ли я некий редкий баг, который с успехом и фанфарами исправят в новой версии fpc, поломав мне весь код?
Это зависит от соглашения о вызове, на какихто будет работать, на какихто нет. Но так делать нельзя, темболее выставляя это как какойто интерфейс наружу

>>Говорить юзеру "Объяви процедуру со 100500 параметрами, потомучто" - не есть правильно.
Это паскаль тут все типизировано и определено на момент компиляции. такчто какраз это и есть правильно.

>>Поэтому максимум что я фиксирую, это устанавливаю верхнюю границу кол-ва параметров и требую для них всех
>>и требую для них всех
там значит неесть правильно, а тут правильно))
MysticCoder
постоялец
Сообщения: 154
Зарегистрирован: 14.09.2013 00:20:28

Сообщение MysticCoder »

по умолчанию параметры передаются через стэк. и вообщем то все равно сколько параметров туда пихать. раз все работает сейчас, значит все нормально, нарушения в работе стэка сразу бы были видны. главное, объяви явно соглашение о вызове типа pascal или cdecl, чтобы компилятор случайно за тебя не объявил) а вообще, почему бы функцию не вызывать через ассемблер, пихая в стэк ровно столько параметров сколько нужно?

Вопрос только в одном: не эксплуатирую-ли я некий редкий баг, который с успехом и фанфарами исправят в новой версии fpc, поломав мне весь код?

а тут никто не даст гарантии) просто потому что это поведение не задокументировано как нормальное
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

Вообще, есть альтернатива, если есть время и желание с ней разбираться - VarDispProc.
Т.е. можно перехватывать вызов метода у вариантной переменной, когда ей присвоен интерфейс. Так сделаны вызовы методов у всяких COM объектов. А т.ч. с русскими буквами и названиями параметров. Т.е. вида method(name='name')
Параметров ессно сколько угодно, компилятор молчит и стек не портится, как в случае если сделать как в первом посте.
xdsl
постоялец
Сообщения: 131
Зарегистрирован: 15.01.2009 12:49:03

Сообщение xdsl »

Mirage писал(а):Вообще, есть альтернатива, если есть время и желание с ней разбираться - VarDispProc.

Пока единственный стоящий ответ, правда не на мой вопрос. К тому-же у меня все работает под Linux, виндовые фишки меня как-то не особо волнуют. Хотя если покопаться, что-то можно и нарыть.
В большинстве остальных постов - набор крайне полезных для ЧСВ словесных кружев от службы психологической разгрузки: "Это никому не надо. Аминь.", "Так делать нельзя, потому-что нельзя.", "Если получается, значит можно.".
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

Ты бы не пердалировал, а сказал спасибо что выше мягко выражались
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

xdsl писал(а):Когда приходит время вызывать юзеровскую процедуру, то вызываю ее с максимальным кол-м аргументов, вне зависимости, сколько аргументов в ней было заявлено. И, блин, это работает! Я не верил в это, когда проверял, ждал проблем со стеком, сегфолта или утечек памяти, но работает все без проблем, debian 8,9, altlinux 7,8, fpc 2.6.4. 3.0.0, 3.0.2.

Вопрос только в одном: не эксплуатирую-ли я некий редкий баг, который с успехом и фанфарами исправят в новой версии fpc, поломав мне весь код?

Дайте угадаю. Архитектура x64? Скорее всего, вы используете побочный эффект соглашения вызова System V fastcall на x64, когда первые 6 или 13 (?) параметров передаются через регистры, а чистку жизнедеятельности делает вызывающая сторона, по максимуму в вашем случае. Смотрите ассемблерный подстрочник, компилируйте и проверяйте под x86 32 бита.
Ответить