avva: (Default)
[personal profile] avva
(эта запись будет интересна программистам, знающим C, и сочувствующим)

Две задачки - первая старая и известная, вторую только что придумал.

1. Напишите код на C, который определяет, в какую сторону растет стек на машине, где его запустили - вверх или вниз.

2. Напишите код на C, который проверяет, кто очищает стек от аргументов в конце работы функции - сама функция или тот, кто ее вызывает, после ее возвращения.

Обратите внимание, что обе задачи можно решить многими способами; интересней придумать решения, которые делают - по возможности, т.к. совсем без этого не обойтись - меньше предположений о том, как ведут себя компилятор и железо.

Комментарии скрывать не буду. Очень рекомендую подумать самому перед тем, как смотреть на решения там.

Date: 2009-09-17 10:41 am (UTC)
From: [identity profile] avva.livejournal.com
pascal, fastcall, stdcall - все они не делают C-шную функцию не-C-шной. Они просто меняют соглашение вызова. Это соглашение не является частью стандарта языка. Насчет переменного числа аргументов см. объяснение выше.

Date: 2009-09-17 11:07 am (UTC)
From: (Anonymous)
Насчет переменного числа аргументов см. объяснение выше.

Вы об этом?

Кроме того, чистка стека фунцкией совместима с переменным числом аргументов, просто требует предоставить функции информацию об их числе в каждом случае с помощью дополнительного скрытого бухгалтерского аргумента.

Ну, можно и так. Создатели VisualC пошли более простым путем: если я компилирую вышеприведенный код с указанием, что соглашение вызова по умолчанию - stdcall, то компилятор все равно компилирует все, что связано с f(...) как cdecl. То есть стек чистит по-прежнему вызывающий.

Date: 2009-09-17 11:25 am (UTC)
From: [identity profile] avva.livejournal.com
Да, я знаю, что в Visual C ничего такого не пытались сделать, и правильно. Но возможность тем не менее есть. Не говоря уж о том, что можно вообще стеком не пользоваться для аргументов. Как ни крути, cdecl нельзя считать неким необходимым свойством 'настоящей C-шной функции'.

Date: 2009-09-17 11:50 am (UTC)
From: (Anonymous)
и правильно

Вот и мне кажется, что это правильно. Скажем так, cdecl - наиболее естественное для С соглашение о вызове.

Вот, кстати, еще один (законный) кусок кода:

int main() { f(0); f(0, 1); f(0, 1, 2); }

int f(int x, int y) { return 0; }

Здесь на момент компиляции main не известно, сколько аргументов у f, и - более того - даже не известно, имеет ли f фиксированное или переменное число аргументов (так что если для функций с переменным числом аргументов используется "хитрый трюк", то мы все равно не знаем, надо ли здесь применять этот трюк). Если мы считаем, что функция - cdecl, проблемы нет: мы можем сгенерировать код, который не будет вызывать никаких проблем со стеком. Но если функция не cdecl, откомпилировать main становится затруднительно (если в VisualC указать, что соглашение по умолчанию - stdcall, то это и не компилируется).

Ну и переопределения типа функций будет вызвать проблемы со стеком (по наличию которых выше и предлагается определять используемое соглашение вызова).

Так что мне очень трудно представить себе, что может толкнуть создателей компилятора на отказ от cdecl, как "естественного" соглащения вызова.

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

Date: 2009-09-17 11:59 am (UTC)
From: (Anonymous)
P.S. Разумеется, если "хитрый трюк" используется во всех функциях (то есть при каждом вызове функции передается неявный параметр, говорящий, сколько байт из стека она должна очистить после выполнения), то все будет работать. В том числе и изменение типа функции - так что предложенное выше решение второй задачи не сработает.

Date: 2009-09-17 12:33 pm (UTC)
From: (Anonymous)
Приношу свои извенения за "не известно" - последнее время меня преследуют приступы своеобразного jamais vu: правильное написание какого-нибудь слова вдруг кажется мне незнакомым, и я начинаю "исправлять" его. Хорошо хоть я пишу анонимно.

December 2025

S M T W T F S
  123 4 56
78 9 10 11 1213
1415 1617181920
21 22 23 24 2526 27
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Dec. 29th, 2025 04:48 pm
Powered by Dreamwidth Studios