在 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_s
或borrow someone else's implementation。
这与您乍一看可能认为的不同。
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_s
或borrow someone else's implementation。