C++17有什么新内容:错误C4996:“getenv”:此函数或变量可能不安全。考虑改用_dupenv_s

3

我想尝试在Linux和Windows中获取环境变量,所有的文档都指向使用std::getenv,但是当我在Windows 10上使用Visual Studio 2019进行编译时,出现了以下错误:

error C4996: 'getenv': This function or variable may be unsafe. Consider using _dupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS

这是函数:

std::string Utils::getEnvVar(std::string const& key)
{
    char* val = std::getenv(key.c_str());
    return val == NULL ? std::string("") : std::string(val);
}

我只找到了这个线程,但我不明白如何解决跨平台的问题。

1
如果你更广泛地搜索错误信息,而不明确指定getenv,那么你应该能够找到更多关于这个“问题”以及可能的解决方案的结果。作为一个快速的解决办法,错误信息本身就包含了如何禁用警告的提示。 - Some programmer dude
1
MS VS2019对一些旧的C调用、访问原始指针和缓冲区等不太友好。他们有一定道理:可能会被错误使用,从而在程序中创建后门,使其易受攻击。因此,你需要说服VS,确实想要使用它。 - JHBonarius
请查看关于“为什么”的此评论 - Aykhan Hagverdili
在Windows上,使用GetEnvironmentVariableW函数。创建第三个函数,将Windows上的GetEnvironmentVariableW和Linux上的getenv封装成一个通用接口。 - Aykhan Hagverdili
1个回答

2
编译器报错如下:
错误 C4996: 'getenv': 此函数或变量可能不安全。考虑使用 _dupenv_s 替代。若要禁用已过时警告,请使用 _CRT_SECURE_NO_WARNINGS。
此警告仅适用于 MSVC,它警告使用了不安全的 C 标准函数。
如果只需要在 MSVC 上进行编译,则可以考虑使用 _dupenv_s 替代。
如果需要跨平台兼容性,则可以选择使用 _CRT_SECURE_NO_WARNINGS 来禁用已过时警告,这是一个定义,只需添加 #define _CRT_SECURE_NO_WARNINGS 即可。另一个解决方案是禁用警告 (#pragma warning(disable: 4996))。
还可以参见 从 Visual Studio 项目中默认删除安全警告 (_CRT_SECURE_NO_WARNINGS)

但是 std::getenv 的实际问题是什么? - Bernd
我找到了另一个关于此问题的帖子:https://dev59.com/pXRB5IYBdhLWcg3wa2m2 - Bernd
@Bernd,我不知道微软认为getenv有什么问题。在getenvgetenv_s的文档中都没有提到。阅读安全函数时,也许他们想要更好的参数验证和增强的错误报告。或者他们想要防止代码错误地写入返回char*而不是const char**getenv(...)吗? - Werner Henze
@WernerHenze 你可以查看这个评论来了解“为什么”。 - Aykhan Hagverdili
这里可以看到,"_dupenv_s使用全局变量_environ指向的环境副本来访问环境。"因此,警告建议的替代方法与getenv相同。 - Werner Henze
@Werner,另一种选择是使用Win32中的GetEnvironmentVariableW函数。 - Aykhan Hagverdili

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接