我应该在MSVC - C上使用安全版本的POSIX函数吗?

Nav*_*K N 6 c cross-platform deprecated compiler-warnings visual-c++

我正在编写一些C代码,预计将在多个编译器上编译(至少在MSVCGCC).因为我是C语言的初学者,所以我打开了所有警告并且警告被视为错误(-Werror在GCC和/WXMSVC中)以防止我犯下愚蠢的错误.

当我编译一些strcpy在MSVC 上使用的代码时,我收到警告,比如

warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

我有点困惑.许多常用功能在MSVC上已弃用.我应该在Windows上使用此安全版本吗?如果是,我应该包装strcpy像,

my_strcpy()
{
#ifdef WIN32
 // use strcpy_s
#ELSE
 // use strcpy    
}
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?

R..*_*R.. 5

每当您在非常量大小的缓冲区之间移动数据时,您必须(喘气!天哪!)实际考虑它是否适合。使用声称是“安全”的函数(如 MS 特定的strcpy_s或 BSD strlcpy)将保护您免受一些明显的缓冲区溢出情况的影响,但不会保护您免受字符串截断导致的错误。在计算必要的缓冲区大小时,它也不会保护您免受整数溢出的影响。

除非您是处理 C 字符串的专家,否则我建议您忘记特殊函数并注释将执行可变长度/位置写入的每一行代码,并说明您在程序中的这一点是如何知道的您将要使用的长度/偏移量在缓冲区大小的范围内。对您也对大小/偏移量执行算术的行执行此操作 - 记录您如何知道算术不会溢出,并在您发现不知道时添加溢出测试。

另一种方法是将所有字符串处理完全包装在一个字符串对象中,该对象将缓冲区的长度与字符串一起存储,并在需要放大字符串时自动重新分配,然后仅const char *在需要时用于对字符串的只读访问将它们传递给系统函数或其他库。这将牺牲您对 C 的期望性能,但它会帮助您确保不会犯错误。只是不要把它带到极端。有没有必要复制这样的东西strchrstrstr在你的字符串包装等。只需提供复制字符串对象、连接它们和截断它们的方法,然后使用现有的库函数操作const char *您就可以做任何您想做的事情。


Sec*_*ure 4

SO 上有很多关于这个话题的讨论。我确信,像 strncpy、strlcpy 之类的常见嫌疑人会再次出现在这里。只需在搜索框中输入“strcpy”并阅读一些较长的线程即可获得概述。

我的建议是:无论您的最终选择是什么,最好遵循 DRY 原则并继续像 my_strcpy() 示例中那样执行。不要在代码中到处乱扔原始调用,使用包装器并将它们集中在您自己的字符串处理库中。这将减少总体代码(样板文件),并且如果您以后改变主意,您可以在一个中心位置进行修改。

当然,这会带来一些其他的麻烦,特别是对于初学者来说:内存处理责任和界面设计。两者都是一个独立的主题,5 个人会给你 10 条如何做的建议。中央库通常有一个很好的效果,它强制执行一个决定,您将在整个代码库中遵循该决定,而不是在模块 A 中使用方法 a,在模块 B 中使用方法 b,从而在尝试将 A 与 B 连接时给您带来麻烦。 ..