17

这篇 MSDN 文章指出 getcwd() 已被弃用,应该改用与 ISO C++ 兼容的 _getcwd,这就提出了一个问题:是什么让 getcwd() 不符合 ISO 标准?

4

7 回答 7

26

有一个很好的讨论PJ Plauger回答了这个问题

我是那个在 1983 年坚持将 C 程序可用的名称空间划分为:

a)由实现为程序员的利益而定义的那些(例如 printf)
b)为程序员保留的那些(例如 foo)
c)为实现保留的那些(例如 _unlink)

即使在那时我们也知道“实现”过于单一——通常不止一个来源提供了部分实现——但这是我们当时能做的最好的事情。标准 C++ 引入了命名空间来提供帮助,但它们只实现了其既定目标的一小部分。(当你标准化纸老虎时会发生这种情况。)

在这种特殊情况下,Posix 提供了一个类别 (a) 名称列表(例如 unlink),当且仅当您包含某些标头时,您应该定义这些名称。由于 C 标准从 Unix(与 Posix 相同的来源)窃取了它的头文件,因此其中一些头文件在历史上是重叠的。尽管如此,编译器警告应该以某种方式考虑支持的环境是“纯”标准 C++(柏拉图式的理想)还是混合的 C/C++/Posix 环境。微软目前帮助我们这些可怜的程序员的尝试没有考虑到这一点。它坚持把unlink当作一个(b)类名,是短视的。

好吧,GCC 不会在严格的 C 模式下声明 POSIX 名称,至少(尽管它仍然在 C++ 模式下如此):

#include <stdio.h>

int main() {
    &fdopen;
    return 0;
}

输出使用-std=c99

test.c: In function 'main':
test.c:4: error: 'fdopen' undeclared (first use in this function)

您必须通过使用功能测试宏或不通过任何特定标准明确告诉它您正在混合 C/Posix 中操作。然后,它将默认gnu89采用混合环境 ( man feature_test_macros)。显然,MSVC 没有这种可能性。

于 2009-03-15T13:22:03.290 回答
20

标准中未指定的函数应该以下划线为前缀,以表明它们是特定于供应商的扩展或遵循非 ISO 标准。因此,这里的“合规性”是微软在这个特定函数的名称中添加下划线,因为它不是 ISO 标准的一部分。

于 2009-03-15T12:17:23.100 回答
4

正如其他人已经指出的那样,getcwd 不包含在 ISO C++ 中,而是POSIX /IEEE Std 1003.1 的一部分。

Microsoft 已决定在其 C 标准库中包含一些最常用的 POSIX 函数(但在这些函数前加上下划线以从本质上阻止它们的使用)。

于 2009-03-15T12:28:16.397 回答
4

作为记录,getcwd()ISO 并未弃用。它被微软“弃用”。Microsoft 重写了许多 C 函数——通常考虑到更好的安全性(例如,也接受max_length参数的字符串函数)。然后他们让他们的编译器吐出这些警告,我认为这是虚假的,因为没有标准组弃用任何声明为弃用的函数。

于 2009-07-07T19:04:23.970 回答
3

据我所知,getcwd() 从未成为 ISO 标准 C++ 的一部分。_getcwd() 绝对不是,因为标准名称不会以下划线开头。

事实上,MSDN 文章链接到一个手册页,说明它是在direct.h中声明的,它不是标准 C++ 头文件。这篇文章在我看来是假的。

于 2009-03-15T12:13:42.110 回答
3

要添加到 Dan Olson 的帖子:请参阅MSDN 上的ANSI C 合规性页面

Microsoft 特定函数和全局变量的名称以下划线开头。这些名称只能在您的代码范围内本地覆盖。例如,当您包含 Microsoft 运行时头文件时,您仍然可以通过声明同名的局部变量来本地覆盖名为 _open 的 Microsoft 特定函数。但是,您不能将此名称用于您自己的全局函数或全局变量。

于 2009-03-15T12:19:12.627 回答
3

MSDN 文章对于普通人从快速阅读中得出的结论有些令人困惑(如果他们没有以非常仔细的律师眼光阅读它)。

MSDN 文章说的是:getcwd() 不符合 ISO C++ 标准。为了遵守函数命名的 ISO C++ 标准(这是 getcwd 违反的),微软在函数的前面正确地放了一个 _,所以同样的函数变成了 _getcwd()。这是符合 ISO C++ 的函数命名方式,因为 getcwd() 和 _getcwd() 不是 ISO C++ 标准函数,而是 Microsoft(供应商)特定或实现特定函数。

这篇文章没有说明获取工作目录的 C++ ISO 标准调用是什么……尽管人们往往一眼就能读到。

于 2010-01-27T23:28:06.183 回答