Открыть список
Как стать автором
Обновить

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

Разработка под Windows
Перевод
Автор оригинала: Raymond Chen
Если в документации сказано, что вы должны вызвать функцию, значит, вы должны. Возможно, функция ничего не делает, но это не значит, что она ничего не будет делать в будущем.

Сегодняшний пример — функция GetEnvironmentStrings, которая возвращает все переменные окружения текущего процесса в одном блоке для изучения на досуге. Когда вы с этим закончите, предполагается, что вы используете FreeEnvironmentStrings. Так сказано в документации, и если вы это сделаете — вы в порядке (you're in good shape).

Однако, некоторые заметили, что в Windows NT4 версия FreeEnvironmentStrings для Unicode ничего не делает. Другими словами, Uniсode блок переменных окружения не нуждается в удалении. Когда вы вызываете GetEnvironmentStrings, ядро возвращает просто прямой указатель на настоящие переменные окружения (которые, поскольку это Windows NT, хранятся в Unicode). Поскольку ничего не выделяется, ничего не надо удалять.

Проблема с этим в том, что если кто-то в это время вызовет SetEnvironmentVariable, блок переменных окружения изменится прямо в руках того, кто вызвал GetEnvironmentStrings.

Упс.

Чтобы исправить это (в комментариях Раймонд Чен пишет, что это было сделано в Windows Vista — Л. Ц.), функция GetEnvironmentStrings была изменена, и возвращает копию блока переменных окружения, даже если вызвать версию для Unicode. Соответствующая функция FreeEnvironmentStrings удаляет эту копию.

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

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

Всегда есть какая-то причина для правил, которые с первого взгляда выглядят глупыми. («Вызвать эту функцию, которая ничего не делает»). Изменения в реализации могут сделать их не такими тупыми в будущем.

(Спасибо моему коллеге Neill Clift за информацию, которая привела к сегодняшней статье)


Раймонд Чен — известный разработчик команды Windows Shell. В Microsoft с 1992 года, работал над OS/2, Windows 95, DirectX и последниями версиями Windows.
Известен своим блогом The Old New Thing, рассказывающем об истории Windows-программирования с фокусом на обратную совместимость.


UPD: Перенес в новый коллективный блог. Спасибо за карму!
Теги:The Old New Thingwindowswinapi
Хабы: Разработка под Windows
Всего голосов 64: ↑58 и ↓6 +52
Просмотры1.5K

Комментарии 29

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

Похожие публикации

Лучшие публикации за сутки