这篇MSDN文章指出,getcwd()已被废弃,应该使用符合ISO C++的_getcwd。这引出了一个问题:是什么导致getcwd()不符合ISO标准?
关于这个问题有一个很好的讨论,P.J. Plauger在其中回答了这个问题。
我就是1983年坚持认为C程序中的名称空间应该被分为以下三类的那个家伙:
a)由实现定义、对程序员有用的名称(例如printf)
b)保留给程序员使用的名称(例如foo)
c)保留给实现使用的名称(例如_unlink)我们当时知道,“实现”太过庞大 - - 往往不止一个源提供了实现的一部分 - - 但那是我们当时能做到的最好的。标准C ++引入了命名空间来帮助,但它们只实现了部分目标。(当你把一个纸老虎标准化时就会发生这种情况。)
在这个特定的情况下,Posix提供了一个类别(a)名称列表(如unlink),只有在包含某些头文件时才定义。由于C标准从Unix中窃取了它的头文件,并且与Posix使用了相同的源,因此这些头文件在历史上有重叠之处。 然而,编译器警告应该有一种方法来考虑支持的环境是“纯”标准C ++(柏拉图式理想)还是混合C / C ++ / Posix环境。微软目前帮助我们这些可怜的程序员的尝试未能考虑到这一点。它坚持将unlink视为类别(b)名称,这是近视眼的。
好吧,在严格的C模式下,GCC不会声明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没有这个可能性。
标准中未指定的函数应该以下划线开头,表示它们是供应商特定扩展或遵循非ISO标准。 因此,此处的“兼容性”是指Microsoft需要在该特定函数的名称前加下划线,因为它不是ISO标准的一部分。
应该说明的是,getcwd()
函数没有被ISO弃用,而是被微软“弃用”了。微软重写了许多C函数——通常考虑了一些更好的安全性(例如,字符串函数也需要一个max_length
参数)。然后他们让编译器输出这些警告,但我认为这些警告是没必要的,因为任何标准组织都没有弃用任何声明为弃用的函数。
getcwd()
也被 GNU 废弃了。请参阅手册页:“由于可移植性和安全原因,已弃用使用 getwd()。” - Björn Lindqvistgetcwd()
(http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html)。 - Max Lybbert正如其他人已经指出的那样,getcwd不包括在ISO C++中,但是它是POSIX/IEEE Std 1003.1的一部分。
微软决定将一些最常用的POSIX函数包含在其C标准库中(但使用下划线作为前缀以实质上阻止它们的使用)。
Microsoft特定函数和全局变量的名称以单个下划线开头。这些名称只能在代码范围内本地覆盖。例如,当您包含Microsoft运行时头文件时,仍然可以通过声明同名的局部变量来本地覆盖名为_open的Microsoft特定函数。但是,您不能将此名称用于自己的全局函数或全局变量。