9

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

当您尝试使用它时,它会运行,

从 Visual C++ 2005 开始不推荐使用此 POSIX 函数。请改用符合 ISO C++ 标准的 _stricmp。

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

4

4 回答 4

13

ISO C 为将来的扩展保留了某些标识符(参见此处),包括以“str”开头的任何内容。

于 2009-12-27T01:14:37.327 回答
12

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

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

也就是说,GCC 工具链对某些功能有点草率 -mktemp()等。但是,尽管有警告(这是有道理的),但它确实可以成功编译和链接。

我注意到 MSVC 在其关于snprintf()等人的引擎盖上也有一只蜜蜂。如果它们的功能符合 C99 标准(以及编译器的其余部分),那么就永远不会有溢出的风险——标准要求空终止,这与 Microsoft 的声明相反。

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

有趣的是,同样污染用户名称空间的 Microsoft API 调用并未被弃用或重命名。

于 2009-12-27T02:19:41.127 回答
3

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

于 2009-12-27T01:04:46.113 回答
2

strcmpi在 Visual C++ 2008 中完全消失了,所以如果你打算升级,你一定要注意弃用。

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

根据微软的文档_stricmp,听起来strcmpi有些做法会导致一些不直观的排序(包括规范化为小写,而不是简单地将大小写视为不相关)。听起来像_stricmp做一个自然期望的事情需要更多的努力。

于 2009-12-27T01:16:05.127 回答