简体   繁体   English

为什么getcwd()不符合ISO C ++?

[英]Why is getcwd() not ISO C++ compliant?

此MSDN文章指出getcwd()已被弃用,而应使用与ISO C ++兼容的_getcwd,这引发了一个问题:是什么使getcwd()不符合ISO?

There is a good discussion about that. 关于这一点有很好的讨论 PJ Plauger answers to this PJ Plauger对此回答

I'm the guy who insisted back in 1983 that the space of names available to a C program be partitioned into: 我是1983年坚持要求将C程序可用名称空间划分为的人:

a) those defined by the implementation for the benefit of the programmer (such as printf) a)为实现程序员的利益而由实现定义的内容(例如printf)
b) those reserved to the programmer (such as foo) b)保留给程序员的那些(例如foo)
c) those reserved to the implementation (such as _unlink) c)保留给实现的那些(例如_unlink)

We knew even then that "the implementation" was too monolithic -- often more than one source supplies bits of the implementation -- but that was the best we could do at the time. 即使在那时,我们仍然知道“实施”过于单一-经常有多个源提供实施的某些部分-但这是我们当时能做的最好的事情。 Standard C++ has introduced namespaces to help, but they have achieved only a fraction of their stated goals. 标准C ++引入了名称空间来提供帮助,但是它们仅实现了既定目标的一小部分。 (That's what happens when you standardize a paper tiger.) (这就是在标准化纸老虎时发生的情况。)

In this particular case, Posix supplies a list of category (a) names (such as unlink) that you should get defined when and only when you include certain headers. 在这种特殊情况下,Posix提供了(a)类名称(例如,取消链接)的列表,只有当您包括某些标头时,才应定义它们。 Since the C Standard stole its headers from Unix, which is the same source as for Posix, some of those headers overlap historically. 由于C标准从Unix窃取了其标头(与Posix的来源相同),因此其中一些标头在历史上是重叠的。 Nevertheless, compiler warnings should have some way of taking into account whether the supported environment is "pure" Standard C++ (a Platonic ideal) or a mixed C/C++/Posix environment. 但是,编译器警告应采用某种方式来考虑所支持的环境是“纯”标准C ++(柏拉图式的理想环境)还是混合的C / C ++ / Posix环境。 The current attempt by Microsoft to help us poor programmers fails to take that into account. Microsoft当前帮助我们贫穷的程序员的尝试没有考虑到这一点。 It insists on treating unlink as a category (b) name, which is myopic. 它坚持将取消链接视为近视类别(b)。

Well, GCC will not declare POSIX names in strict C mode, at least (though, it still does in C++ mode): 好吧,GCC至少不会在严格的C模式下声明POSIX名称(尽管它仍然在C ++模式下声明):

#include <stdio.h>

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

Output using -std=c99 使用-std=c99输出

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

You will have to tell it explicitly that you are operating in a mixed C/Posix by using feature test macros or not passing any specific standard. 您必须明确地告诉它,您正在使用功能测试宏或未通过任何特定标准在混合C / Posix中进行操作。 It will then default to gnu89 which assumes a mixed environment ( man feature_test_macros ). 然后它将默认为gnu89 ,它假定使用混合环境( man feature_test_macros )。 Apparently, MSVC does not have that possibility. 显然,MSVC没有这种可能性。

Functions not specified in the standard are supposed to be prefixed by an underscore as an indication that they're vendor-specific extensions or adhere to a non-ISO standard. 未在标准中指定的功能应加下划线作为前缀,以表明它们是特定于供应商的扩展或遵循非ISO标准。 Thus the "compliance" here was for Microsoft to add an underscore to the name of this specific function since it's not part of the ISO standard. 因此,此处的“合规性”是为了使Microsoft在此特定功能的名称上添加下划线,因为它不属于ISO标准。

As others have already pointed out, getcwd is not included in ISO C++, but is part of POSIX /IEEE Std 1003.1. 正如其他人已经指出的那样,getcwd不包含在ISO C ++中,而是POSIX / IEEE Std 1003.1的一部分。

Microsoft has decided to include some of the most commonly used POSIX functions in their C standard library (but prefix these functions with an underscore to essentially discourage their usage). Microsoft已决定在其C标准库中包括一些最常用的POSIX函数(但应在这些函数前加上下划线以实质上阻止其使用)。

For the record, getcwd() wasn't deprecated by ISO. 记录,ISO并没有弃用getcwd() It was "deprecated" by Microsoft. 它已被Microsoft“弃用”。 Microsoft rewrote many C functions -- often with a little better security in mind (say, string functions that also take a max_length parameter). Microsoft重新编写了许多C函数-通常考虑到更好的安全性(例如,字符串函数也带有max_length参数)。 They then had their compiler spit out these warnings, which I consider bogus because no standards group deprecated any of the functions declared deprecated. 然后,他们让编译器吐出这些警告,我认为这是虚假的,因为没有标准组反对任何声明不赞成使用的函数。

The MSDN article is somewhat confusing in what a normal person would conclude from just a quick reading (if they don't read it with a very careful lawyer eye). MSDN的文章使普通人从快速阅读中得出的结论有些令人困惑(如果他们没有以非常仔细的律师眼来阅读它的话)。

What the MSDN article says is: getcwd() is not compliant with the ISO C++ standard. MSDN文章所说的是:getcwd()不符合ISO C ++标准。 To comply with that ISO C++ standard for naming of functions (which is what getcwd violates), Microsoft properly put an _ on the front of the function, so the same function becomes _getcwd(). 为了符合该函数命名的ISO C ++标准(这是getcwd违反的标准),Microsoft在函数的前面放置了一个_,因此相同的函数成为_getcwd()。 That is the ISO C++ compliant way of naming the function because getcwd() and _getcwd() are not an ISO C++ standard function, but are a Microsoft (vendor) specific, or implementation specific function. 这是对该函数命名的符合ISO C ++的方式,因为getcwd()和_getcwd()不是ISO C ++标准函数,而是特定于Microsoft(供应商)或特定于实现的函数。

The article does not indicate what a C++ ISO standard call to get the working directory would be... though thats what folks tend to read at a quick glance. 这篇文章没有指出要获取工作目录的C ++ ISO标准调用是什么……尽管那是人们往往一眼就能读到的。

As far as I'm aware getcwd() has never been part of ISO Standard C++. 据我所知,getcwd()从未成为ISO标准C ++的一部分。 _getcwd() definitely isn't, as standard names will not begin with an underscore. _getcwd()绝对不是,因为标准名称不会以下划线开头。

In fact, the MSDN article links to a man page that says it is declared in direct.h , which is not a Standard C++ header file. 实际上,MSDN文章链接到手册页,该手册页说它是在direct.h中声明的,这不是标准C ++头文件。 The article seems bogus to me. 这篇文章对我来说似乎是虚假的。

To add on to Dan Olson's post: See ANSI C Compliance page on MSDN 要添加到Dan Olson的帖子中:请参见MSDN上的ANSI C合规性页面

The names of Microsoft-specific functions and global variables begin with a single underscore. Microsoft特定函数的名称和全局变量以单个下划线开头。 These names can be overridden only locally, within the scope of your code. 这些名称只能在代码范围内在本地覆盖。 For example, when you include Microsoft run-time header files, you can still locally override the Microsoft-specific function named _open by declaring a local variable of the same name. 例如,当您包含Microsoft运行时头文件时,仍然可以通过声明同名的本地变量来本地覆盖名为_open的Microsoft特定函数。 However, you cannot use this name for your own global function or global variable. 但是,不能将此名称用于自己的全局函数或全局变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM