我正在编写一些 C 代码,预计可以在多个编译器上编译(至少在 MSVC
和 GCC
上)。由于我是 C 的初学者,我打开了所有警告并将警告视为错误(GCC 中的 -Werror
和 MSVC 中的 /WX
)以防止我犯傻错误。
当我在 MSVC 上编译一些使用 strcpy
的代码时,我收到类似警告,
警告 C4996:“strcpy”:此函数或变量可能不安全。考虑改用 strcpy_s。要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS。有关详细信息,请参阅联机帮助。
我有点懵。 MSVC 弃用了许多常用函数。我应该在 Windows 上使用这个安全版本吗?如果是,我是否应该包装 strcpy
之类的东西,
my_strcpy()
{
#ifdef WIN32
// use strcpy_s
#ELSE
// use strcpy
}
有什么想法吗?
最佳答案
每当您在非恒定大小的缓冲区之间移动数据时,您必须(喘息!我的天啊!)实际上考虑它是否适合。使用声称“安全”的函数(如 MS 特定的 strcpy_s
或 BSD strlcpy
)将保护您免受一些明显的缓冲区溢出条件,但不会保护您免受字符串截断导致的错误。在计算必要的缓冲区大小时,它也不会保护您免受整数溢出的影响。
除非您是处理 C 字符串的专家,否则我建议您忘记特殊函数并注释每一 代码行,这些代码将执行可变长度/位置写入,并说明您如何知道,此时在程序中,您将要使用的长度/偏移量在缓冲区大小的范围内。对你也在大小/偏移量上执行算术的行执行此操作 - 记录你如何知道算术不会溢出,如果你发现你不知道,则添加溢出测试。
另一种方法是将所有字符串处理完全包装在一个字符串对象中,该对象将缓冲区的长度与字符串一起存储,并在需要扩大字符串时自动重新分配,然后仅使用 const char *
用于在需要将字符串传递给系统函数或其他库时对字符串进行只读访问。这会牺牲很多您期望从 C 获得的性能,但它会帮助您确保不会出错。只是不要把它带到极端。无需在字符串包装器中复制 strchr
、strstr
等内容。只需提供复制字符串对象、连接它们和截断它们的方法,然后使用在 const char *
上运行的现有库函数,您几乎可以做任何您想做的事情。
关于c - 我应该在 MSVC - C 上使用安全版本的 POSIX 函数吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3203169/