strcmpi 重命名为_strcmpi?

问题描述 投票:0回答:5

在 MSVC++ 中,有一个函数 strcmpi 用于不区分大小写的 C 字符串比较。

当您尝试使用它时,它就会出现,

从 Visual C++ 2005 开始,已弃用此 POSIX 函数。请改用符合 ISO C++ 的 _stricmp。

我不明白的是为什么 ISO 不希望 MSVC++ 使用 strcmpi,为什么 _stricmp 是首选方式,为什么他们要费心重命名该函数,以及以下划线开头的函数如何符合 ISO 标准。我知道这一切一定有一个原因,我怀疑它是因为 strcmpi 是非标准的,也许 ISO 希望非标准扩展以 _下划线开头?

c++ c string strcmp
5个回答
13
投票

ISO C 保留某些标识符以供将来扩展(请参阅此处),包括以“str”开头的任何标识符。


11
投票

IMNSHO,这是微软的说法“不要将 Unix 软件放在 Windows 机器上”。这个问题有几个令人沮丧的方面:

  1. strcmpi()
    不是 POSIX 函数 - 相关函数在
    <strings.h>
    中定义,并称为
    strcasecmp()
    等。
  2. 即使您明确请求支持 POSIX 函数,微软也认为您不能使用 POSIX 名称,而必须在它们前面加上可怜的下划线。
  3. AFAIK,没有办法覆盖 MSVC 编译器对此问题的看法。

也就是说,GCC 工具链对某些功能有点不稳定 -

mktemp()
等人。然而,尽管有警告(这是有道理的),它仍然可以成功编译和链接。

我注意到 MSVC 的帽子里也有一只蜜蜂关于

snprintf()
等人。如果它们的函数符合 C99 标准(以及编译器的其余部分),那么永远不会有任何溢出风险 - 该标准要求 null 终止,这与 Microsoft 的声明相反。

我还没有找到一个真正好的解决方案来解决这个问题——我不确定是否有解决方案。一种可能性是创建一个标头(或一组标头)以将所有实际的 POSIX 名称映射到 Microsoft 对它们的误解。另一个方法是创建一个具有正确 POSIX 名称的简单函数库,每个函数都调用 Microsoft 版本的名称(为您提供大量四行函数的集合 - 声明符行、左大括号、右大括号和调用 POSIX 函数名称的 Microsoft 变体的 return 语句。

有趣的是,Microsoft API 调用也污染了用户的名称空间,但却没有被弃用或重命名。


3
投票

以下划线和小写字母开头的名称如果在全局命名空间中声明,则由 C++ 标准保留用于 C++ 实现。这可以防止它们与您自己的代码中的相似名称发生冲突,您自己的代码不得使用此命名约定。


2
投票

strcmpi
在 Visual C++ 2008 中完全消失,因此如果您打算升级,您一定要注意弃用。

_ 并不使函数成为 ISO 标准,只是随着语言的发展,以 _ 开头的函数添加起来更安全,因为这是为语言保留的命名空间部分之一。

根据 Microsoft 的

_stricmp
文档,听起来
strcmpi
有一些做法会导致一些不直观的排序(包括标准化为小写而不是简单地将大小写视为无关)。听起来
_stricmp
需要付出更多的努力才能做到人们自然期望的事情。


0
投票

我维护 POSIX 兼容性的方法:

// Check if on MS compiler (newer than Visual Studio 2015)
#if ( _MSC_VER > 1900 )
// redefine the name
#ifndef stricmp
#define stricmp _stricmp
#endif
#endif // _MSC_VER
© www.soinside.com 2019 - 2024. All rights reserved.