close 与 _close、read 与 _read、write 与 _write - 有什么区别?

Men*_*des 4 c++ sockets visual-studio-2012

I\xc2\xb4m 将一个简单的socket客户端程序从 Linux 迁移到 Windows (VS2012)。该程序使用常规的close,readwrite函数。

\n\n

在 VS2012 中编译时,I\xc2\xb4m 收到以下警告:

\n\n
warning C4996: 'close': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _close\n\nwarning C4996: 'write': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _write\n\nwarning C4996: 'read': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _read\n
Run Code Online (Sandbox Code Playgroud)\n\n

解决方案很简单 - 只需添加下划线 - 但是......

\n\n

close_closeread_readwrite和 之间的真正区别是什么_write

\n\n

只需更改为下划线版本就会保留相同的行为吗?

\n

Lig*_*ica 5

\n

在VS2012中编译时,我\xc2\xb4m收到以下警告

\n
\n\n

哇,这些都是可笑的误导性信息。干得好,微软。

\n\n

他们似乎认为_close,_read_write是 ISO C++ 函数。
\n他们不是!

\n\n
\n

close_closeread和 、_readwrite之间的真正区别是什么_write

\n
\n\n

微软显然已经重新实现了 POSIX 功能closeread并且write. 不同之处在于,在重新实现时,他们选择使用前导下划线重命名这些函数,因为 ISO C++ 标准规定,前导下划线是实现(即 Visual Studio)应该用于内部/内置函数的内容。

\n\n
\n

只需更改为下划线版本就会保留相同的行为吗?

\n
\n\n

我不会在这里列举各种潜在的差异。当然,有关这些函数如何工作以及如何使用它们的完整信息,请阅读它们的文档。但直接的答案并不是该行为与名称类似的 POSIX 函数的行为相同。

\n


Kaz*_*Kaz 5

该错误信息是政治声明,而不是事实真相。

由于_close声称“符合 ISO C++”,暗示 POSIXclose命名符合 ISO C++。

那完全是垃圾。

几十年来,带下划线的名称就是 Microsoft 在其库中实现 POSIX 子集模仿的方式。(具有扩展,例如_spawn*函数族,弥补了 的不足fork)。

这些名称符合 ISO C 和 C++,因为它们仅限于保留的命名空间。如果(程序员)使用标识符(如_close外部名称),则行为是未定义的。但这并不意味着语言实现者在其公共 API 中使用此类标识符是个好主意。它们对于内部(可能未记录)标识符很有用。微软曾经做出了一个令人遗憾的选择,创建了一些名称丑陋的 API,后来制作了一条编译器错误消息来追溯证明它的合理性。

但是,您看,Windows API 充满了不限于_[a-zA-Z0-9_]*命名空间的标识符,例如CreateWindow、 和WaitForSingleObject

如果close不是“ISO C++ 符合”,那么这些也不是!

事实上,ISO C 和 C++ 允许实现者拥有名称位于普通命名空间中的附加库函数,例如closeWaitForSingleObject。类似的名称_close仅在未来的 ISO C 或 C++ 标准可能不会使用它的意义上才符合。但实际上,任何主要 API(如 POSIX 或 Windows)的标识符也是如此。

如果您是系统 API 世界中的一个小玩家,并且您给一个函数一些简短的名称(即,英语词典单词),即使它现在不与 ISO C 冲突,未来的标准也可以运行它的众所周知的推土机在上面。POSIX 函数不存在发生这种情况的危险。