Предупреждение C4996: эта функция или переменная может быть небезопасной - по сравнению с GCC в POSIX - PullRequest
20 голосов
/ 26 ноября 2010

Я заметил, что компиляторы MS выдают "устаревшие" предупреждения для cstdlib функций, таких как getenv.MS изобрела свой собственный стандарт, такой как _dupenv_s.

Вопрос 1

AFAIK. Главная «небезопасная» вещь касается повторного входа *.Поскольку CRT от MS помечены как «многопоточные» (/MT), почему бы просто не заменить getenv на реентерабельную, поточно-ориентированную версию?Как будто кто-то зависит от небезопасного поведения?

Вопрос 2

Я скомпилировал тот же код с GCC g++ -Wall -Wextra -Weff++ -pedantic foo.cpp, и он не выдает никаких предупреждений.Итак, я думаю, что это не проблема на POSIX?Как это решается?(Ладно, может быть, они просто изменили поведение getenv, было бы неплохо подтвердить это).

* Слишком обобщенно говорить, что речь идет только о повторном входе.Конечно, у нас есть такие вещи, как strncpy_s, который полностью меняет подпись и имеет дело с размером буфера.Но не меняет сути этого вопроса

Ответы [ 3 ]

23 голосов
/ 26 ноября 2010
  1. В нормальном мире ответом будет "конечно, нет, это было бы глупо!"Однако в этом мире, похоже, нет конца мучительно плохо продуманному недокументированному поведению, от которого люди будут опускаться до зависимости. Раймонд Чен имеет большую коллекцию таких анекдотов (анекдотов?) В своем блоге.Например, отвратительная практика использования ошибки в загрузчике для совместного использования локальных переменных потока между exe и DLL .Когда у вас столько клиентов, сколько у Microsoft, единственный безопасный вариант - никогда не рисковать нарушением обратной совместимости.

  2. Разница в предупреждениях заключается в том, что cl.exe выходит из строявыделить потенциальную проблему безопасности, а g++ нет.getenv и puts и друзья все еще не работают в POSIX, но (по крайней мере для getenv) в стандартной библиотеке нет более безопасной альтернативы.И, в отличие от Microsoft, люди GNU, вероятно, рассматривают стандартный вызов библиотеки с потенциальными проблемами безопасности как меньшее зло, чем более безопасный, но зависящий от платформы вызов библиотеки.

9 голосов
/ 26 ноября 2010

Меня раздражает, что Microsoft решила сделать это. Я знаю, как безопасно вызывать все функции, я не хочу или не нуждаюсь в этих дополнительных предупреждениях.

Просто установите _CRT_SECURE_NO_WARNINGS и покончите с этим. Это действительно так глупо.

7 голосов
/ 26 ноября 2010

Для конкретного случая getenv это действительно не реентерабельно и не безопасно для потоков.Что касается того, почему Microsoft не просто заменяет его, вы не можете взять этот интерфейс и сделать его реентерабельным (вы можете почти сделать его «поточно-ориентированным» с локальным хранилищем потоков, но он все равно не будет реентерабельным).1003 * Даже если вы просто убрали getenv, существует проблема, связанная с тем, что у вас есть переменная environ, которая потребует серьезной поддержки на уровне компилятора, чтобы сделать поток безопасным, поскольку это всего лишь данные.

Действительно, использование переменных окружения для чего-либо, кроме «установки его перед запуском процесса или при запуске процесса и только чтения с него с этого момента», вероятно, закончится слезами, если у вас большеодна нить.setenv и putenv не имеют достаточно богатого интерфейса, чтобы выразить что-то вроде «установить этот набор переменных среды атомарно», а также getenv не имеет способа выразить «читать этот набор переменных среды атомарно»,

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...