Difference between getch() and _getch() - c++

What is the difference between the two function that are defined in the conio.h header file-
getch() and _getch().
Is there a difference in the decalaration? Or is it simply a difference due to updated standards?

It is part of a decision by Microsoft a couple of years ago to interpret the C++ standard more rigidly. It says that all names in the global namespace which start with an underscore are reserved for use by the implementation. This means that getch is not a reserved name, but _getch is.
So Microsoft figured that "this function, and every other POSIX function, is kind of supplied by the implementation. Let's rename them by prepending an underscore, so we're able to keep it inside the "reserved" part of the global namespace. That way, there's no chance of name clashes with user-supplied functions.
You could say that these are good intentions, or that it's just an evil attempt at breaking POSIX code. I don't know what their true motivation was, but the end result is that according to Microsoft, getch is deprecated, and you should use _getch instead.

Both of these functions are non-standard (i.e. they are not in C++ ISO standard). They are extensions provided by your particular toolchain, and as such, you have to check for differences in its documentation.

Related

Is it safe to use "yes","no","i","out" as name for variables/enum?

I have read the document about naming rule of C++, they seems to be usable names.
However, in practice, when I tried to create a variable/enum with a name like iter, yes, no, out, i, Error, etc. , Visual Studio will strangely use italic font for them.
I can only guess that they are reserved for special thing, and IDE (e.g. refactoring/rename process) might act strangely if I use such names.
Is it safe to use those names in practice? Am I just too panic?
Sorry if it is too newbie or an inappropriate question.
I doubt about it for a few weeks but too afraid to ask.
These names are valid and will not cause any "harm", the standard only says:
Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the
implementation for any use.
Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
Which means that all your names are fine to use in user-code. Visual Studio might just have a thing for these names as i and iter are usually used in looping.
These names are not reserved in standard C++, as explained by Rick Astley. An implementation may choose to accept additional reserved words to provide language extensions, such as ref class in C++/CLI. In some cases, such as with ref class, where ref is a contextual keyword, these extensions only make otherwise ill-formed programs well-formed in the scope of the extended language. In other cases, an otherwise well-formed program may change its meaning or become ill-formed. In the former case, the implementation is still conforming to the C++ standard, as long as it issues all mandatory diagnostics; in the latter case, it is certainly not conforming.
It is considered good practice to make the latter kind of extensions optional e.g. using a command line option, so that the implementation still has a mode in which it is fully standards compliant. My immediate guess is that VC++ in fact does allow you to write well-formed programs containing yes, no, i, iter which will behave as required by the standard (implementation bugs notwithstanding).
The IDE is a different beast, though. It is considered to be outside of the scope of the C++ standard, and might discourage or even stop you from writing perfectly well-formed code. That would still be a quality of implementation issue, or an issue of customer satisfaction, if you will.

The standard C function declaration syntax (WINAPI) [duplicate]

This question already has answers here:
What does "WINAPI" in main function mean?
(4 answers)
Closed 7 years ago.
I know you might think this question already been answered but it is not, or at least it was not very clear to me.
int WINAPI WinMain (){}
This is a pseudo form of the famous winmain function.
My question is about the calling convention WINAPI, in particular its placement between the "return type" and the "function name". Is this Standard C? Because I referenced the Brian W. Kernighan and Dennis M. Ritchie book and I didn't see this form.
I also have searched for its meaning and they said it's a macro to place _stdcall instead. So please don't tell me the question is duplicated.
And here is one of the questions that might be very close to mine
What does "WINAPI" in main function mean?
I want a clear answer for this WINAPI: Is it standard C? So I can place a calling convention after the return type in any function declaration and I then give it to any C compiler in the world? Or is it something will work only on Microsoft compilers? And if so, can anyone impose their rules on the C syntax?
I'm sorry I know my question might be trivial for many of you, but I searched everywhere about the functions declaration syntax and all sources denied this calling convention place.
The essential answer: No. A function declaration, as defined by the C language standard, has no elements between the return type and the function name. So int __bootycall myFunc(int qux) is not standard C (or C++), even though C implementations are allowed to reserve __customIdentifiers for their own exclusive use.
However.
The need for calling-convention specifiers (e.g. __cdecl) is clear; a lot of (especially early non-UNIX [especially MS-DOS]) platforms had more than one calling convention to choose from, and specifying the calling convention of a function was as important as, if not more important than, the parameter list of that function. Hence the need to slot a little something extra in there.
At that time (even before C89), there was no provision made for architecture-specific function attributes (presumably because C, designed for the sole purpose of implementing UNIX utilities, didn't need any). This would later be remedied in C99, and if C99 had existed at that point, it's likely that __cdecl et al. would have been function attributes, not random identifiers shoved in there. But as it was, when the need arose to specify non-default calling conventions, there were four reasonable places to put it: Before the return type, between the return type and the function name, between the function name and the opening parenthesis of the argument list, and after the argument list.
I'm speculating here, but it seems like the second option would have made the most sense. This was pre-C++, remember; there was no post-arglist-const, and the only thing that could show up before the return type was static, which specified linkage rather than anything about the function per se. That left before or after the function name, and separating the function name from its argument list would have reduced readability. That left the slightly unusual position between the return type and the function name as the best of a bad bunch.
The rest is history. Later compilers took advantage of the nascent __attribute__ syntax to put the calling convention keyword in a more appropriate place, but DOS-based compilers (of which Microsoft C was one of the first) shoved it after the return type.
Both the __stdcall and the position of the keyword are Microsoft specific. Any compiler vendor is able to add non-standard syntax to their implementation.
At the very top of this MSDN article:
Microsoft Specific
It also mentions the WINAPI macro at the end of the page:
In the following example, use of __stdcall results in all WINAPI function types being handled as a standard call: [...]`
This form works on both Microsoft C++ Compiler and the MinGW toolchain, which implements GCC for Windows.
But in general GCC uses this other form using it's attributes:
int WinMain() __attribute__((stdcall)) // or WINAPI if using the macro
{}
It's possible however that in the future we have those in a more standard syntax (the stdcall part still being platform specific) by using the recent C++11 generalized attributes such as.
[[ms::stdcall]]
int WinMain() {}
In fact both GCC and Clang already supports the standard generalized attributes as an alternative to the compiler specific attribute syntax.
The answer to your clear question:
WINAPI, Is it a standard C?
is No. __stdcall is a Microsoft extension.
WINAPI is a macro defined in windows.h, which expands to __stdcall. Both windows.h and __stdcall are Windows-specific -- no industry-wide standard defines any aspect of their meaning.
The C and C++ standards do define keywords that have related effects on a function definition: inline, _Noreturn (C2011), and static. All of these keywords are normally placed before the return type, but if I'm reading C2011 correctly, this is not actually required by the syntax: you could perfectly well write
int static foo(void) { return 42; }
These keywords are called function specifiers and storage class specifiers.
Do not confuse them with type specifiers and type qualifiers, which can also appear in this position, but modify the return type when they do.

ISO C++ and the infamous underscore [duplicate]

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?
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.
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.
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).
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.
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.
As far as I'm aware getcwd() has never been part of ISO Standard C++. _getcwd() definitely isn't, as standard names will not begin with an underscore.
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. The article seems bogus to me.
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).
What the MSDN article says is: getcwd() is not compliant with the ISO C++ standard. 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(). 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.
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.

strcmpi renamed to _strcmpi?

In MSVC++, there's a function strcmpi for case-insensitive C-string comparisons.
When you try and use it, it goes,
This POSIX function is deprecated beginning in Visual C++ 2005. Use the ISO C++ conformant _stricmp instead.
What I don't see is why does ISO not want MSVC++ to use strcmpi, and why is _stricmp the preferred way, and why would they bother to rename the function, and how is a function beginning with an underscore ISO conformant. I know there must be a reason for all this, and I'm suspecting its because strcmpi is non-standard, and perhaps ISO wants non-standard extensions to begin with an _underscore?
ISO C reserves certain identifiers for future expansion (see here), including anything that starts with "str".
IMNSHO, this is Microsoft's way of saying "Do not put Unix software on Windows machines". There are several frustrating aspects to the problem:
strcmpi() is not a POSIX function - the relevant functions are defined in <strings.h> and are called strcasecmp() etc.
Even if you explicitly request support for POSIX functions, Microsoft thinks that you may not use the POSIX names but must prefix them with the wretched underscore.
AFAIK, there isn't a way of overriding the MSVC compiler's view on the issue.
That said, the GCC tool chain gets a bit stroppy about some functions - mktemp() et al. However, it does compile and link successfully, despite the warnings (which are justified).
I note that MSVC also has a bee in its bonnet about snprintf() et al. If their function conformed to the C99 standard (along with the rest of the compiler), then there would never be any risk of an overflow - the standard requires null termination, contrary to the claims of Microsoft.
I haven't got a really good solution to this problem - I'm not sure there is one. One possibility is to create a header (or set of headers) to map all the actual POSIX names to Microsoft's misinterpretation of them. Another is two create a library of trivial functions with the correct POSIX name that each call down onto the Microsoft version of the name (giving you a massive collection of four-line functions - the declarator line, an open brace, a close brace, and a return statement that invokes the Microsoft variant of the POSIX function name.
It's funny how the Microsoft API calls, which also pollute the user's name space, are not deprecated or renamed.
Names begining witth an underscore and a lower case letter are reserved by the C++ Standard for the C++ implementation, if they are declared in the global namespace. This stops them from clashing with similar names in your own code, which must not use this naming convention.
strcmpi goes away altogether in Visual C++ 2008, so you should definitely heed the deprecation if you ever intend to upgrade.
The _ doesn't make the function ISO standard, it's just that functions beginning with _ are safer to add as the language evolves because that's one of the parts of the namespace reserved for the language to use.
According to Microsoft's documentation for _stricmp, it sounds like strcmpi has some practices that result in some unintuitive orderings (including normalizing to lower case instead of simply treating case as irrelevant). Sounds like _stricmp takes more pains to do what one would naturally expect.

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

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?
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.
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.
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).
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.
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.
As far as I'm aware getcwd() has never been part of ISO Standard C++. _getcwd() definitely isn't, as standard names will not begin with an underscore.
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. The article seems bogus to me.
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).
What the MSDN article says is: getcwd() is not compliant with the ISO C++ standard. 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(). 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.
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.