Заполнение va_list

Программирование на интерфейсе означает соблюдение «контракта», созданного с использованием этого интерфейса. И поэтому, если ваш интерфейс IPoweredByMotor имеет метод start(), будущие классы, которые реализуют интерфейс, будь то MotorizedWheelChair, Automobile или SmoothieMaker, при реализации методов этого интерфейса добавят гибкости вашей системе потому что один кусок кода может запустить двигатель множества различных типов вещей, потому что все, что нужно знать одному коду, - это то, что они отвечают start(). Неважно , как они начинают, просто они должны начинать .

25
задан kristina 12 June 2009 в 18:38
поделиться

3 ответа

Это плохая идея , потому что абстракция va_list предназначена для того, чтобы скрыть некоторые мрачные детали компилятора / архитектуры, касающиеся указателей стека и тому подобного. И после инициализации он в значительной степени привязан к области видимости функции. Если вы развернете стек и ссылаетесь на предыдущие кадры va_args вне области видимости, все может пойти плохо. Вы можете передавать их, но ...

ожидайте ошибок

См .: http://lists.freebsd.org/pipermail/freebsd-amd64/2004-August/001946.html

Также проверьте man (3) va_copy и друзья для более безопасной обработки va_args и их передачи.

IMHO, материал va_args не очень изящный. В прошлом я имел дело с этим, инициализируя структуры / непрозрачные указатели в куче, а затем используя арифметику указателей для обработки данных.

14
ответ дан 28 November 2019 в 21:42
поделиться

Я понимаю и согласен с предупреждениями Эйдена - va_list и друзья опасны, так как они скрывают низкоуровневые соглашения о вызовах. Но ... в этой ситуации, я думаю, у тебя нет другого выхода. Поместите статический ... функцию в файл .c , чтобы никто другой не мог ее увидеть, своего рода прокси для функции, которую вам нужно вызвать, черт возьми, проверьте это и готово. Только убедитесь, что вы не выставляете вариативные аргументы вверх по цепочке вызовов.

6
ответ дан 28 November 2019 в 21:42
поделиться

Ваше представление о функции прокси, которая создает va_list , является правильным способом сделать это. Нет необходимости, чтобы этот прокси имел общедоступную область действия. Однако, если вы можете обнаружить, что прокси уже существует. Например, во многих реализациях библиотеки sprintf () является просто прокси для vsprintf () .

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

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

5
ответ дан 28 November 2019 в 21:42
поделиться
Другие вопросы по тегам:

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