Вопрос или проблема
C11 добавил новые функции с проверкой границ в стандартную библиотеку, такие как getenv_s
.
Однако, когда я подключаю <cstdlib>
, у меня нет std::getenv_s
, только getenv_s
(глобальное пространство имен).
На cppreference есть следующая заметка:
Как и во всех функциях с проверкой границ, наличие getenv_s гарантируется только в том случае, если реализован
__STDC_LIB_EXT1__
и если пользователь определяет__STDC_WANT_LIB_EXT1__
как целочисленную константу 1 перед подключением <stdlib.h>.
Даже когда я определяю __STDC_WANT_LIB_EXT1__
как 1
, мой компилятор (MSVC C++23) не находит функцию std::getenv_s
.
Разве <cstdlib>
не должен переносить каждый символ из <stdlib.h>
в пространство имен std
?
Функции с суффиксом _s
являются частью необязательного Приложения K в стандартах C. Поскольку они необязательны, они могут не поддерживаться всеми реализациями.
В C++ определение того, будет ли подключение заголовка C++ включать эти функции в область глобального пространства имен, зависит от реализации, но они никогда не становятся доступными в области пространства имен std
. Они не полностью интегрированы в стандартную библиотеку C++ как функции стандартной библиотеки C, которые являются обязательными.
Смотрите [headers]/10.
Ответ или решение
Функция getenv_s
действительно не является частью cstdlib
в стандартной библиотеке C++. Это связано с тем, что функции с суффиксом _s
(включая getenv_s
) относятся к дополнительному разделу K стандарта C, который определяет функции с контролем границ. Доступность этих функций является необязательной, и они могут не поддерживаться во всех реализациях.
При использовании C++ в рамках стандартной библиотеки реализовано следующее: включение заголовка C++ (например, <cstdlib>
) не гарантирует автоматическое включение всех символов заголовка C (в данном случае <stdlib.h>
) в пространство имен std
. Согласно стандарту C++, реализация может определить, будут ли эти функции доступны в глобальном пространстве имен или нет, но они никогда не становятся частью пространства имен std
.
Чтобы обеспечить доступ к функциям с суффиксом _s
, можно воспользоваться следующими советами:
-
Убедитесь, что вы определили
__STDC_WANT_LIB_EXT1__
как1
перед включением любого из заголовков C. Например:#define __STDC_WANT_LIB_EXT1__ 1 #include <cstdlib>
-
Обратите внимание, что поддержка функций с суффиксом
_s
зависит от конкретной реализации компилятора. В вашем случае, при использовании MSVC с C++23, некоторые функции из Annex K могут не быть доступны в пространстве именstd
, даже если вы правильно определили нужные макросы. -
Проверьте документацию вашего компилятора, чтобы узнать о поддержке функций с контролем границ, поскольку это может различаться между версиями и конфигурациями.
Таким образом, когда вы подключаете <cstdlib>
, функции, такие как getenv_s
, будут доступны в глобальном пространстве имен, однако они не являются частью пространства имен std
, что объясняет ваше наблюдение. Это утверждение корректно согласуется с тем, как реализованы функции из Annex K в стандартной библиотеке.