【问题标题】:Using strcpy() in Visual Studio 2013在 Visual Studio 2013 中使用 strcpy()
【发布时间】:2015-06-16 14:00:25
【问题描述】:

这不是您第一眼看到的重复。

Visual Studio 中的 strcpy() 弃用已为人所知几年,当您尝试将 C 代码从 GCC 移植到 MSVC 时,这是一个难题。

在 Visual Studio 2013 中,所有定义_CRT_SECURE_NO_WARNINGS 的变通方法都无法解决问题 - 编译仍然失败出现此错误(称为“警告”,但实际上是导致编译失败的错误)。

我的问题是在代码中是否有一种优雅的方法来解决它?

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

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

你能告诉我吗:

  • 如果您认为这是解决此可移植性问题的好方法?
  • 如何正确编写这样的宏?
  • 还有其他建议吗?

【问题讨论】:

  • 定义 _CRT_SECURE_NO_WARNINGS 然后继续。
  • strlen(src) 应该是strlen(src)+1
  • _CRT_SECURE_NO_WARNINGS 在 VS2013 中对我来说很好用。确保在预编译的头文件中或在C/C++::Preprocessor 下的项目设置中定义它。
  • 如前所述放入_CRT_SECURE_NO_WARNINGS,或放入stdafx.h并重建。忽略微软的建议。
  • Everyone please read this 在让任何不聪明的 Microsoft cmets 认为 strcpy 不安全之前。

标签: c visual-c++ visual-studio-2013


【解决方案1】:

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

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

从另一端开始会更好:不要在 MSVC 上定义一个将 strcpy 打扮成 strcpy_s 的宏,而是在 gcc 中定义一个宏以将 strcpy_s 打扮成 strcpy 以保持可移植性。

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

【讨论】:

  • 在 MSVC 中会发生什么?它将在strcpy_s() 的多个定义上失败。我想我会为这两个平台实现my_strcpy()...
  • @SomethingSomething 你不应该在 MSVC 上定义自己的 strcpy_s,只能在 gcc 上。为此使用条件编译。
  • 如何表明它是 MSVC?有#ifdef SOMETHING_THAT_INDICATES_MSVC 吗?
  • @SomethingSomething _WIN32 是一个常见的。这是Q&A about that
  • @SomethingSomething 我建议改为_MSC_VER
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    • 2015-08-27
    相关资源
    最近更新 更多