98. Не используйте неизвестные аргументы (троеточия)
98. Не используйте неизвестные аргументы (троеточия)
Резюме
Наличие троеточий в С++ — опасное наследие С. Избегайте их в своих программах; используйте вместо этого высокоуровневые конструкции и библиотеки С++.
Обсуждение
Функции с переменным количеством аргументов достаточно удобны, однако использование неизвестных аргументов в стиле C — не лучший способ получения таких функций. Эти аргументы имеют много серьезных недостатков.
• Недостаточная безопасность типов. По сути, троеточие говорит компилятору: "Выключи все проверки. С этого момента я все беру на себя, и теперь начинает работать reinterpret_cast". (См. рекомендацию 92).
• Сильное связывание и необходимость согласования вызываемого и вызывающего кода вручную. Проверка типов языком оказывается отключена, так что вызывающий код должен использовать иные способы для сообщения о типах передаваемых аргументов. Такие протоколы (например, форматная строка printf) подвержены ошибкам и небезопасны, поскольку не могут быть полностью проверены ни вызывающим, ни вызываемым кодом. (См. рекомендацию 99.)
• Неопределенное поведение для объектов типов, являющихся классами. Передача чего бы то ни было кроме POD и примитивных типов вместо троеточий приводит к неопределенному поведению в С++. К сожалению, большинство компиляторов даже не предупреждает об этом.
• Неизвестное количество аргументов. Даже в случае простейших функций с переменным количеством аргументов (например, min) вам все равно требуется протокол, позволяющий указать количество передаваемых аргументов. (Как ни смешно, но это, пожалуй, хорошее свойство, поскольку является еще одним препятствием широкому распространению функций с переменным числом аргументов.)
Избегайте троеточий в сигнатурах ваших функций. Избегайте вызова функций с переменным количеством аргументов со своими собственными сигнатурами, даже если это вполне корректные функции из стандартной библиотеки С, такие как sprintf. Вызовы sprintf часто выглядят более компактными и простыми для понимания, чем эквивалентные вызовы с использованием форматирования stringstream и операторов operator<< — так же, как легче сесть в машину, не оборудованную ремнями и подушкой безопасности, да еще и без дверец. Удобства при использовании таких функций не стоят возникающего при этом риска. Функции в стиле printf представляют собой серьезную проблему безопасности (см. [Cowan01]), так что имеется целая отрасль разработки инструментария для поиска ошибок такого рода (см. [Tsai01]).
Лучше использовать безопасные в смысле типов библиотеки, которые поддерживают переменное количество аргументов иными средствами. Например, библиотека форматирования [Boost] использует новейшие средства С++ для совмещения безопасности со скоростью и удобством.
Ссылки
[Boost] • [Cowan01] • [Murray93] §2.6 • [Sutter04] §2-3 • [Tsai01]
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
10.3.1. Аргументы программы
10.3.1. Аргументы программы Есть два типа значений, передаваемых новым программам при их запуске: аргументы командной строки и переменные окружения. Для их использования установлено множество соглашений, но система сама по себе не придерживается их автоматически. Однако
26.2.3. Остаточные аргументы
26.2.3. Остаточные аргументы Многие приложения принимают произвольное количество аргументов командной строки, например, список имен файлов. Когда popt встречает аргумент, перед которым отсутствует дефис -, она считает его таким аргументом и добавляет его в список остаточных
Альтернативные аргументы make
Альтернативные аргументы make Существует еще несколько дополнительных аргументов make, которые могут передаваться во время компиляции. Некоторые из них обсуждаются здесь, но остальные используются внутри файла и на самом деле не имеют никакого значения или практической
Привлекательные аргументы
Привлекательные аргументы Аргументы представляют значения, которые предполагается передавать от одной процедуры к другой. Аргументы назначаются процедуре тогда, когда необходимо, чтобы эта процедура изменяла свое поведение в зависимости от тех значений, которые она
Полезные аргументы
Полезные аргументы Но если аргументы так похожи на обычные переменные, зачем же вообще их использовать? В действительности их можно и не использовать - все, что делают аргументы, можно сделать с помощью обычных переменных. Но аргументы упрощают использование процедур и
5.2.8. Аргументы "за" и "против" сжатия файлов
5.2.8. Аргументы "за" и "против" сжатия файлов Во многих современных Unix-проектах, таких как OpenOffice.org и AbiWord, в настоящее время в качестве формата файлов данных используется XML, сжатый с помощью программ zip(1) или grip(1). Сжатый XML комбинирует экономию пространства с некоторыми
Фактические аргументы
Фактические аргументы Фактический аргумент может быть любым значением базового типа, структурой, объединением или указателем. Все фактические аргументы передаются по значению. Массивы и функции не могут быть переданы как параметры, могут передаваться указатели на эти
9.4.4. Аргументы со значениями по умолчанию
9.4.4. Аргументы со значениями по умолчанию Наличие аргументов со значениями по умолчанию способно расширить множество устоявших функций. Устоявшими являются функции, которые вызываются с данным списком фактических аргументов. Но такая функция может иметь больше
17.5.4. Виртуальные функции и аргументы по умолчанию
17.5.4. Виртуальные функции и аргументы по умолчанию Рассмотрим следующую простую иерархию классов:#include iostreamclass base {public:virtual int foo( int ival = 1024 ) {cout " base::foo() -- ival: " ival endl;return ival;}// ...};class derived : public base {public:virtual int foo( int ival = 2048 ) {cout " derived::foo() -- ival: " ival endl;return ival;}// ...};Проектировщик
Аргументы для gbak -b[ackup]
Аргументы для gbak -b[ackup] исходные-данные- это полный путь и имя файла копируемой базы данных. В Firebird 1.5 это может быть алиас. При копировании многофайловой базы данных используйте имя только первого (первичного) файла базы данных.копия- полный путь и имя файла, куда
Аргументы gbak для восстановления
Аргументы gbak для восстановления исходная-копия- полный путь и имя файла копии gbak. Если копия содержит несколько файлов, укажите только первый (первичный) файл gbak. В POSIX исходной- копией может быть также stdin, в этом случае gbak читает свои входные данные из стандартного ввода