10

This question is about the same subject as strdup or _strdup? but it is not the same. That question asks how to work around MS's renamings, this question asks why they did it in the first place.

For some reason Microsoft has deprecated a whole slew of POSIX C functions and replaced them with _-prefixed variants. One example among many is 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.

What exactly is ISO C++ conformant about _isatty? It appears to me that the MSDN help is totally wrong.

The other questions answer explained how to deal with this problem. You add the _CRT_NONSTDC_NO_DEPRECATE define. Fine. But I want to know what Microsoft's thinking is. What was their point in renaming and deprecating functions? Was it just to make C programmers lives even harder?

Björn Lindqvist
  • 19,221
  • 20
  • 87
  • 122
  • 1
    http://stackoverflow.com/a/7582741/315052 is the answer to your question. Microsoft views POSIX co-opting C and C++ reserved prefixes as a violation. – jxh Jun 15 '16 at 20:39

3 Answers3

14

The fact that _isatty() is ISO C++ conformant makes sense if you think of it like a .

Under ISO C++, the compiler is only supposed to provide the functions in the standard (at least for the standard headers) -- they're not allowed to freely add extra functions, because it could conflict with functions declared in the code being compiled. Since isatty() is not listed in the standard, providing an isatty() function in a standard header would not be ISO C++ compliant.

However, the standard does allow the compiler to provide any function it wants as long as the function starts with a single underscore. So -- language lawyer time -- _isatty() is compliant with ISO C++.

I believe that's the logic that leads to the error message being phrased the way it is.

(Now, in this specific case, isatty() was provided in io.h, which is not actually a C++ standard header, so technically Microsoft could provide it and still claim to be standards-conformant. But, they had other non-compliant functions like strcmpi() in string.h, which is a standard header. So, for consistency, they deprecated all of the POSIX functions the same way and they all report the same error message.)

phuclv
  • 37,963
  • 15
  • 156
  • 475
Steven
  • 754
  • 3
  • 6
  • So *technically* MS is correct and all Unix C runtimes are bugged? But wouldn't that apply for *all* C functions in the runtime then, not just the POSIX-mandated ones? `tmpfile_s` and `wcrtomb_s` appears to not be in the C standard and they don't have any underscores. – Björn Lindqvist Jun 15 '16 at 21:00
  • 2
    I think that's right. Technically, the Unix C runtimes are not ISO-compliant (they're POSIX-compliant). As for tmpfile_s, I think you're correct that there was ummm... some hypocrisy... when those functions were first added. Although, now, I think a lot of the functions have been added to the C++ standard; for example, http://en.cppreference.com/w/c/io/tmpfile indicates tmpfile_s is part of the C11 standard – Steven Jun 15 '16 at 21:05
  • 1
    Oh, I do think "bugged" is too strong of a word. It'd be more accurate to say the Unix C runtimes aren't actually trying to be 100% ISO-compliant in the first place; they're more interested in POSIX-compliance. – Steven Jun 15 '16 at 21:11
  • 1
    That somewhat contradicts the "extensions" MS added themselves to the C library. It looks more hypocritical to me. Primary reason is more likely MS has dropped POSIX support for the rest of the system and tries/tried (such companies take some time to change direction) to bind programmers tighter to their platform. Considering the partly contradicting concepts of POSIX and Windows, this even makes sense from a maintenance view of the libs/system. – too honest for this site Jun 16 '16 at 10:38
2

Names starting with an underscore, like _isatty are reserved for the implementation. They do not have a meaning defined by ISO C++, nor by ISO C, and you can't use them for your own purposes. So Microsoft is entirely right in using this prefix, and POSIX is actually wrong.

C++ has namespaces, so a hypthetical "Posix C++" could define namespace posix, but POSIX has essentially become fossilized - no new innovation in that area.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • 1
    That's not about being "!fossilised", but POSIX being C-based, not C++. And C just does not have custom namespaces. – too honest for this site Jun 15 '16 at 21:29
  • @Olaf: POSIX could have decided to define alternative C++ bindings, there is no technical reason why they had to restrict themselves to one language. Boost stepped into that void, in a sense, and Boost shows much more signs of life. – MSalters Jun 16 '16 at 07:03
  • 1
    POSIX just focuses on providing the foundations. It leaves higher abstraction to other libraries. This actually follows the ideas behind Unix and C. These is common and good practice (modularisation). This is a proven approach. Feel free to engage in a new ISO or IEC/etc. commitee to standardize boost or other OOP lib or maybe start POSIX-3 to cover this layer. – too honest for this site Jun 16 '16 at 10:34
  • 1
    @Olaf: No need for an additional ISO committee to standardize Boost, WG21 already does so. Just check C++11/14/17. – MSalters Jun 16 '16 at 10:52
0

isatty & co., although POSIX, are not standard C, and are provided as "extensions" by the VC++ runtime1.

As such, they are prefixed with an underscore supposedly to avoid name clashes - as names starting with an underscore followed by a lowercase letter are reserved for implementation-defined stuff at global scope. So if, for example, you wanted to use an actual POSIX compatibility layer providing its own versions of these functions, they wouldn't have to fight with the VC++-provided "fake" ones for the non-underscored names.


  1. Extensions which have no presumption to be actually POSIX-compliant, by the way.
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299