Как компилятор C реализует функции с Переменными числами аргументов?

Я присутствовал на техническом интервью несколько дней назад, и меня спросили, Как делает компилятор C implments функция с Переменным количеством аргументов? Как это передает стеку?

Кто-либо знает, или может explian это?

Спасибо, Dan

13
задан skaffman 29 April 2010 в 17:53
поделиться

4 ответа

Он реализует их с помощью макроса va_, например va_start . Именно то, что делают эти макросы, определяется реализацией - другими словами, это будет варьироваться от архитектуры ЦП к архитектуре и от компилятора к компилятору. Но они должны сыграть злую шутку со стеком вызовов C. Как правило, это будет включать в себя взятие адреса последнего указанного параметра в качестве основы, а затем доступ к параметрам с переменным числом аргументов путем выполнения арифметических операций с указателями на этой основе.

7
ответ дан 2 December 2019 в 00:03
поделиться

Посмотрите на va_start, va_arg и va_end. Вот тонна информации по этому поводу.

-1
ответ дан 2 December 2019 в 00:03
поделиться

Насколько вам грустно, что вы получили этот вопрос на техническом собеседовании, я Предположим, что правильным ответом будет:

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

И добавьте несколько идей, почему помещать эти параметры в отдельный массив неудобно.

0
ответ дан 2 December 2019 в 00:03
поделиться

Насколько мне известно, с C ...

  • вызывающая функция помещает аргументы в стек в порядке справа налево.

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


P.S .: Соглашения о вызовах обычно зависят от реализации . То, что я только что описал, известно как соглашение о вызовах "cdecl". Сравните это с соглашением о вызовах, обычно известным как "stdcall", где вызываемая функция отвечает за удаление своих аргументов из стека. По этой причине он не поддерживает списки аргументов переменной длины.


P.P.S .: Как прокомментировал пользователь nategoose, я не упомянул, как на самом деле используются списки переменных аргументов . См., Например, документация POSIX для заголовка для получения дополнительной информации.

10
ответ дан 2 December 2019 в 00:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: