2

当我键入时,编译器 (Visual C++) 总是纠正我flushall();

警告 C4996:“flushall”:不推荐使用此项目的 POSIX 名称。而是使用符合 ISO C++ 的名称:_flushall。

他们都为我工作,有什么区别吗?

4

2 回答 2

9

这个警告是荒谬的;flushall不是 POSIX,据我所知,从来都不是。刷新所有打开的 stdio 流的正确 ISO C 方法是fflush(NULL);.

为了更清楚地说明这个问题,我相信这是 Visual C 用于不属于 C 标准的函数的通用警告消息,但它们的标准库具有某种最低程度的兼容性。这些函数中的大多数类似于openand read,并且以某种模糊的方式对应于同名的 POSIX 函数,并且可以被认为是 stdio 等底层的低级原语。有些,比如flushall,实际上不是来自 POSIX,但只是基于从各种旧版 unice 复制的古怪函数。

由于这些函数实际上不是 C(或 C++)标准的一部分,并且 C 标准(也可能还有 C++ 标准......?)为未在标准中明确定义或保留的应用程序标识符保留,它不是-conformant 以在标准标题名称中公开,例如openflushall. POSIX 通过使用功能测试宏来解决这个问题应用程序可以通过它从实现中显式地保证它想要的命名空间,但 Microsoft 采取了一种方法,即弃用类似 POSIX 的名称并提供一组替代函数,前缀为下划线,这使它们成为保留的命名空间的一部分实施。警告建议您使用这些 Microsoft 特定的名称,以便在您打开选项(可能由编译器开关的宏控制)以在标头中实现严格的命名空间一致性时,您的代码仍然可以编译。

不幸的是,使用带下划线前缀的名称以 Microsoft 推荐的方式编写代码会使您的代码完全不可移植。由于这些名称位于为实现保留的命名空间中,因此其他平台可能碰巧将相同的名称用于执行完全不同的事情的函数,并且由于它们是保留的,因此您将不允许替换或#define围绕它们重新映射它们到其他功能。

简而言之:我会找到生成此警告的警告标志,然后将其关闭。连同那个喷出 FUD 的那个,这样那样的标准函数是“不安全的”,你应该改用 _s 后缀的函数。但是,如果您需要的唯一功能是fflushall(),只需将其替换fflush(NULL);为即可。

于 2012-10-26T17:43:18.873 回答
2

这可以追溯到 1988 年末,当时 Dave Cutler 的团队开始在 Windows NT 上进行开发。设计目标是创建一个具有三个不同 api 层的操作系统,Winapi、OS/2 和 POSIX。POSIX 那时非常新,第一个版本也在 1988 年发布。它被包括在内是因为它被列为美国政府标准 FIPS 151-2 中的一项要求。

那时 Unix 战争开始变得严肃起来。相当恶毒,在竞争的实现中故意存在差异。主要的战斗者是开放软件基金会,一个担心 Sun 日益增长的主导地位的行业组织和 Unix International,一个围绕 AT&T 的组织。直到 1993 年,COSE 联盟(即现在的 Open Group)成立,尘埃落定。

这使得 flushall() 的确切起源很难追查,当时它是非常狂野的西部。微软也从事 C 编译器业务,因此他们当然发布了构建在 POSIX 层上运行的程序的工具,包括声明函数的标头。所以可以肯定的是,flushall 是在他们的工具集中出现的。我没有副本要检查了,被漏水的屋顶摧毁了。

NT Posix 和 OS/2 api 层从未获得太大的吸引力,被 Win32 的巨大成功所掩盖。它们在 2001 年随 XP 版本完全删除。我认为,这也是他们开始弃用原始 Posix 函数名称的时候。显然,当操作系统不再支持这些声明时,保留这些声明已经没有多大意义了。Posix 名称相当笨拙,全局命名空间中的短小写名称会导致许多意外。

然而,它们从未被完全移除,至今仍被记录在案。这就是您收到警告的原因。与其选择,不如选择标准 C 库名称 fflush()。

于 2013-02-14T23:28:07.870 回答