Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is getcwd() not ISO C++ compliant?

Tags:

c++

iso

This MSDN article states that getcwd() has been deprecated and that the ISO C++ compatible _getcwd should be used instead, which raises the question: what makes getcwd() not ISO-compliant?

like image 206
Stuart P. Bentley Avatar asked Mar 15 '09 12:03

Stuart P. Bentley


5 Answers

There is a good discussion about that. P.J. Plauger answers to this

I'm the guy who insisted back in 1983 that the space of names available to a C program be partitioned into:

a) those defined by the implementation for the benefit of the programmer (such as printf)
b) those reserved to the programmer (such as foo)
c) those reserved to the implementation (such as _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. (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. Since the C Standard stole its headers from Unix, which is the same source as for Posix, some of those headers overlap historically. 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. The current attempt by Microsoft to help us poor programmers fails to take that into account. It insists on treating unlink as a category (b) name, which is myopic.

Well, GCC will not declare POSIX names in strict C mode, at least (though, it still does in C++ mode):

#include <stdio.h>

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

Output using -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. It will then default to gnu89 which assumes a mixed environment (man feature_test_macros). Apparently, MSVC does not have that possibility.

like image 170
Johannes Schaub - litb Avatar answered Oct 17 '22 15:10

Johannes Schaub - litb


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. 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.

like image 34
Dan Olson Avatar answered Oct 17 '22 14:10

Dan Olson


As others have already pointed out, getcwd is not included in ISO C++, but is part of 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).

like image 4
cmeerw Avatar answered Oct 17 '22 15:10

cmeerw


For the record, getcwd() wasn't deprecated by ISO. It was "deprecated" by Microsoft. Microsoft rewrote many C functions -- often with a little better security in mind (say, string functions that also take a max_length parameter). They then had their compiler spit out these warnings, which I consider bogus because no standards group deprecated any of the functions declared deprecated.

like image 4
Max Lybbert Avatar answered Oct 17 '22 15:10

Max Lybbert


To add on to Dan Olson's post: See ANSI C Compliance page on MSDN

The names of Microsoft-specific functions and global variables begin with a single underscore. 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. However, you cannot use this name for your own global function or global variable.

like image 3
dirkgently Avatar answered Oct 17 '22 14:10

dirkgently