微软的下划线C函数有什么作用?

10
这个问题与 strdup or _strdup? 相关,但并不相同。那个问题问如何“解决”MS的重命名问题,而这个问题则问为什么它们首先这样做。

由于某种原因,Microsoft 已经弃用了一整套 POSIX C 函数,并用以 '_' 为前缀的新函数替换它们。其中之一的例子是 'isatty':

https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/posix-isatty

This POSIX function is deprecated. Use the ISO C++ conformant _isatty instead.

_isatty在ISO C++中符合什么要求?在我看来,MSDN文档帮助完全是错误的。

另一个回答解释了如何解决这个问题。你可以添加_CRT_NONSTDC_NO_DEPRECATE定义。不错。但我想知道微软的想法是什么。他们重命名和弃用函数的目的是什么?是为了让C程序员的生活更加困难吗?


1
https://dev59.com/z2sz5IYBdhLWcg3w6MJS#7582741 是你问题的答案。微软认为 POSIX 占用 C 和 C++ 保留前缀是一种违规行为。 - jxh
3个回答

14
_isatty()符合ISO C++标准,如果你将其视为的话,这就说得通了。
在ISO C++中,编译器只应提供标准中的函数(至少对于标准头文件是如此)——它们不允许随意添加额外的函数,因为这可能会与正在编译的代码中声明的函数发生冲突。由于isatty()没有列在标准中,因此在标准头文件中提供一个isatty()函数将不符合ISO C++规范。
然而,标准确实允许编译器提供任何以单个下划线开头的函数。所以——现在是语言律师时间——_isatty()是符合ISO C++标准的。
我相信这就是导致错误消息被表述成这样的逻辑。
(现在,在这种特定情况下,isatty()是在io.h中提供的,这实际上不是C++标准头文件,因此从技术上讲,微软公司可以提供它并仍然声称符合标准。但是,他们有其他非符合标准的函数,例如string.h中的strcmpi()。因此,为了保持一致,他们以相同的方式弃用了所有的POSIX函数,并且它们都报告相同的错误消息。)

那么 从技术上讲,微软是正确的,所有 Unix C 运行时都有漏洞?但这难道不适用于运行时中的 所有 C 函数,而不仅仅是 POSIX 规定的函数吗?tmpfile_swcrtomb_s似乎不在 C 标准中,并且它们没有下划线。 - Björn Lindqvist
2
我认为这是正确的。从技术上讲,Unix C运行时不符合ISO标准(它们符合POSIX标准)。至于tmpfile_s,我认为你是正确的,当这些函数首次添加时存在某种虚伪。尽管现在,我认为很多函数已经被添加到C++标准中了;例如,http://en.cppreference.com/w/c/io/tmpfile表明tmpfile_s是C11标准的一部分。 - Steven
1
哦,我认为“bugged”这个词太过强烈了。更准确的说法是Unix C运行时并没有试图在第一时间达到100%的ISO兼容性;他们更关注POSIX兼容性。 - Steven
1
这有点与 MS 自己添加到 C 库的“扩展”相矛盾。在我看来,这更具伪善性。主要原因更可能是 MS 放弃了系统的 POSIX 支持,并试图/曾试图(这样的公司需要一些时间来改变方向)将程序员更紧密地绑定到他们的平台上。考虑到 POSIX 和 Windows 的部分相互矛盾的概念,从 libs/system 的维护视角来看,这甚至是有道理的。 - too honest for this site

2

以下划线开头的名称,例如_isatty,是保留给实现的。它们在ISO C++和ISO C中没有定义的含义,并且您不能将其用于自己的目的。因此,Microsoft在使用此前缀时是完全正确的,而POSIX实际上是错误的。

C++具有命名空间,因此假想的“Posix C++”可以定义namespace posix,但是POSIX基本上已经僵化-在该领域没有新的创新。


1
这不是关于“僵化”的问题,而是因为POSIX基于C语言,而不是C ++。而且C语言根本没有自定义命名空间。 - too honest for this site
@Olaf: POSIX可能会决定定义替代C++绑定,他们没有必要限制自己只使用一种语言。在某种意义上,Boost填补了这个空白,并且Boost显示出更多的生命迹象。 - MSalters
1
POSIX 专注于提供基础功能,高层抽象留给其他库来完成。 这实际上遵循了 Unix 和 C 的思想。 这是一种普遍而良好的实践(模块化)。这是一种行之有效的方法。你可以参与一个新的 ISO 或 IEC / 等委员会来标准化 boost 或其他面向对象编程库,或者启动 POSIX-3 来覆盖此层。 - too honest for this site
1
@Olaf:没有必要成立一个额外的ISO委员会来标准化Boost,WG21已经在做这件事了。只需要查看C++11/14/17即可。 - MSalters

0

isatty等函数虽然符合POSIX标准,但并不是标准C函数,而是由VC++运行时库提供的“扩展”1

因此,它们以下划线为前缀,据说是为了避免名称冲突 - 以下划线开头且后跟小写字母的名称保留用于全局范围内的实现定义内容。例如,如果您想使用一个实际的POSIX兼容层,该层提供自己版本的这些函数,则它们不必与VC++提供的“伪造”函数竞争非下划线名称。


  1. 顺便说一下,这些扩展并没有假定实际上符合 POSIX 标准。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接