【问题标题】:strdup or _strdup?strdup 还是 _strdup?
【发布时间】:2011-11-26 19:10:17
【问题描述】:

当我在 Microsoft Visual C++ 中使用 strdup 时,它会警告我:

警告 C4996:“strdup”:不推荐使用此项目的 POSIX 名称。而是使用符合 ISO C++ 的名称:_strdup。有关详细信息,请参阅在线帮助。

因此看来_strdup 是正确的。

但是当我在 GCC (Fedora Linux OS) 中使用_strdup 时,编译器显示错误:

错误:“_strdup”未在此范围内声明

使用 GCC 和 Linux,编译器不会显示 strdup 的任何错误。

哪个是正确的 - strdup_strdup

注意:我的代码中包含<string.h>

【问题讨论】:

  • 在 C++ 中,考虑使用 std::string 而不是 C 样式的字符串,然后问题就消失了。此外,在 C++ 中,标头只是 <cstring>
  • @Rowland Shaw:我的意思是 GCC 显示 _strdup 的错误,但没有显示 strdup 的任何错误。我的测试平台是 Fedora Linux。
  • 请注意,在 Visual Studio 2013 及更高版本中,这些警告现在是错误。

标签: c++ c visual-studio strdup


【解决方案1】:

哪个是正确的?

strdup 是一个完全正确的 POSIX 函数。然而,它不属于该标准,并且 ANSI C 标准保留了一些(广泛的)函数名称类以供进一步使用。其中,有

  • str和小写字母开头的函数名

因此,MS 们决定将strdup 替换为_strdup

我会继续使用strdup。 C 委员会不太可能将strdup 定义为 POSIX 以外的其他东西。 #define strdup _strdup 或使警告静音。

顺便说一句,我希望你看到这也适用于你的函数,比如 string_list 等。

【讨论】:

  • 看来,与 POSIX 不同,ISO C 在不久的将来可能永远不会定义 strdup。请参阅 N1118 关于“no-implicit-malloc 规则”。
  • @FrankHB:从不说从不strdup 终于进入了下一个 C 标准:open-std.org/jtc1/sc22/wg14/www/docs/n2479.pdf 但我想你是对的不久的将来,在 C 世界中,10 年很快。
  • 我多年来一直意识到这一点。很高兴看到 WG14 打破了他们的隐含规则。
【解决方案2】:

strdup 不是标准 C++ 函数。但它显然是一个 Posix 函数,无论如何它是自 K&R C 以来一直存在的众所周知的函数。所以如果你绝对必须使用它,不要担心任何可能的名称冲突,只需写strdup 以获得最大的便携性。

【讨论】:

  • 问题是,在 MSVC 中有大量的“POSIX-compliant _foo”。如果你想要“安静的编译”(特别是在大型项目中)和移植的可能性,这很烦人它到 GCC。例如 _fileno、_isatty(使用 Flex 解析器生成器时)和许多其他系统函数。目前我在 #ifdef _MSC_VER 中添加了许多#defines,但我总是愿意寻求更好的解决方案。
  • @ThomasGandor:#ifdef 的一种替代方法是通过编译器的头文件搜索路径使用编译器特定的头文件选择。 #define 的一种替代方法(因为宏不尊重范围)是使用 inline 转发器函数。
  • 只需使用-D_CRT_NONSTDC_NO_DEPRECATE。它应该可以在任何地方工作,对于 MSVC,它会使其关闭。它的唯一目的是在移植应用程序时惹恼用户。它也可能有一些用例,其中 MSVCRT 变体的行为不同于 POSIX/C99 变体。不过我暂时想不出来
  • @mnunberg: _snprintf() 仔细检查文档。
  • 对于额外的疯狂,VS2015 会产生这些错误,并且您必须使用多个非标准的#defines 才能恢复正常行为。
【解决方案3】:

您可以#define _CRT_NONSTDC_NO_DEPRECATE 禁用此警告。

【讨论】:

    【解决方案4】:

    如果您只是想避免警告消息:

    项目-> 属性 -> C/C++ -> 预处理器 -> 预处理器定义

    编辑并添加

    _CRT_NONSTDC_NO_DEPRECATE

    【讨论】:

      【解决方案5】:

      strdup 是 POSIX:

      http://pubs.opengroup.org/onlinepubs/9699919799/functions/strdup.html

      _strdup 是特定于 Windows 的:

      http://msdn.microsoft.com/en-us/library/y471khhc(v=vs.80).aspx

      在 Unix 上,使用 strdup。在 Windows 上,使用 _strdup。就是这么简单。如果你需要在 Unix 和 Windows 之间编写可移植的代码:

      • 使用与系统相关的宏(例如 _WIN32 与 _POSIX_VERSION)来选择正确的函数(但请注意,宏可能取决于特定的预先存在的包含文件):

      http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html

      http://msdn.microsoft.com/en-us/library/b0084kay(v=vs.80).aspx

      • 使用标准函数重新实现 strdup:strlen、malloc 和 memmove。

      • 使用跨平台实用程序库,例如 glib:

      http://developer.gnome.org/glib/2.28/glib-String-Utility-Functions.html#g-strdup

      请注意,Visual C++ 消息表明 _strdup 属于 C++ 标准,但这是错误,因为它可以在 C++ 标准上进行验证。它只是使用下划线前缀作为函数的“命名空间”。

      http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3376.pdf

      【讨论】:

      • MSVC 从不暗示_strdup 属于C++ 标准!它只是说_strdup 是一个符合 C++ 标准的名称。正如你和其他人所说,strdupPOSIX系统使用的保留名称,所以MS认为它可以解决保留名称的问题
      【解决方案6】:

      不懂 C++。

      C Standard 没有描述任何具有strdup 名称的函数(尽管该名称是保留的)。 为了便于移植,在 C 中,您最好将其替换为 mallocstrcpyfree

      【讨论】:

      • 我同意这一点。该功能一直是多余的。
      • 我刚刚检查了(可能的)next C Standard (C2011?) 并且strdup 也没有被它描述。
      • @pmg:10 年后,strdup 将最终进入下一个 C 标准:open-std.org/jtc1/sc22/wg14/www/docs/n2479.pdf 但我想在 C 标准世界中,10 年很快。
      【解决方案7】:

      不是警告,而是高版本vs报错。

      使用宏#ifdef WIN32切换

      【讨论】:

      • 与评论自己的答案一样有用。
      • 最好用#ifdef _MSC_VER检查微软编译器,因为WIN32平台上可能有MINGW或其他编译器。
      • @AlexanderUshakov 是的
      猜你喜欢
      • 1970-01-01
      • 2012-12-10
      • 2012-10-10
      • 2013-08-29
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      • 2010-12-09
      相关资源
      最近更新 更多