在 Visual Studio 2013 年使用 strcpy()

Using strcpy() in Visual Studio 2013

这与您乍一看可能认为的不同。

Visual Studio 中的 strcpy() 弃用已经为人所知几年了,因为当您尝试将 C 代码从 GCC 移植到 MSVC 时会遇到困难。

在 Visual Studio 2013 中,定义 _CRT_SECURE_NO_WARNINGS 的所有解决方法都无法解决问题 - 编译仍然因这个错误而失败(它被称为 "warning",但它是实际上是导致编译失败的错误)。

我的问题是代码中有没有优雅的方法可以解决?

例如,这样的宏对我有很大帮助:

#ifdef SOMETHING_THAT_INDICATES_ITS_MSVC_COMPILER
    Some macro that makes the following substitution:
        strcpy(dest, src) -> strcpy_s(dest, strlen(src), src)
#endif

你能告诉我吗:

如果 src 没有正确终止,这将崩溃,如果 dst 对于 src 来说太短——这就是实际使用 strcpy_s() 的原因。您必须采用最短的源 (- 1) 和目标。但是,由于这些主要来自指针,因此长度信息不再可用。

正确(和可移植)解决方案是修复受影响的代码以正确使用 strcpy_s()hackish 解决方案 可能 只是将长度值传递给 strcpy_s() 比任何字符串可能具有的长度都大,例如RSIZE_MAX,这是最大值。允许的长度。这不会比 strcpy() 或您的方法更安全或更不安全。 免责声明:我强烈反对这样做!请改用正确的代码!.

您建议的宏以不安全的方式使用 strcpy_s,即好像它是 strcpy。使用不安全的原因是第二个参数是为了表示目的地的长度,而不是源的长度。如果源代码足够长导致内存溢出,strcpy_s 将无济于事。

您的方法可以作为一种使编译器静音的方法,但弃用是有原因的:strcpy 不安全,因此您应该努力改用 strcpy_s

从另一端着手会更好:与其在 MSVC 上定义一个将 strcpy 打扮成 strcpy_s 的宏,不如在 gcc 中定义一个宏来打扮 strcpy_s作为 strcpy 以保持可移植性。

要实现这一点,请检查您的源代码,并将所有使用的 strcpy 替换为 strcpy_s,将目标大小作为第二个参数传递。然后通过在gcc上删除中间参数有条件地定义一个将strcpy_s转换为strcpy的宏,在gcc上编写自己的strcpy_sborrow someone else's implementation