This question already has answers here:
Why is the gets function so dangerous that it should not be used?
(13 answers)
Closed 1 year ago.
Based on the most recent draft of C++11, C++ refers to ISO/IEC 9899:1999/Cor.3:2007(E) for the definitions of the C library functions (per §1.2[intro.refs]/1).
Based on the most recent draft of C99 TC3, The gets function is obsolescent, and is deprecated. (per §7.26.9/2)
Can I safely say that gets() is deprecated in both C and C++?
Deprecated means you shouldn't use it and it might be removed in the future. Since both standards say it is deprecated, that means it is deprecated, officially.
Does it matter? The only way you can ever use gets is if stdin is known to be attached to a file whose contents you have full control over. This condition is almost impossible to satisfy, especially on multiprocess systems where other processes may modify files asynchronously with respect to your program. Therefore, for all practical purposes, any program using gets has undefined behavior (i.e. there are possible inputs/environmental conditions for which it will have undefined behavior), and in particular UB which is likely to lead to privilege compromise if your program has higher privileges than the provider of the data.
Edit: OK, here's one safe use of gets, about the only one I can think of right off...
if (feof(stdin)) gets(buf);
Of course some buggy implementations (possibly including glibc..?) permit reads even when the EOF indicator is already set for a stream, so....
Even code which would be broken by the removal of gets() from the library would, after such removal, be less broken than it was before such removal. I suppose it might be necessary for compiler vendors to include it in a "fully-standard compliant" mode, but the number of circumstances where it could safely be used is so vanishingly small that it would probably be reasonable to exclude it from a "normal" build.
It's going to be a while until C++11 is implemented everywhere.
Also, most compilers doesn't even fully support C99 yet.
Microsoft's, for instance, does not.
So no, it's not deprecated in both C and C++.
Well it was removed altogether from the C11 standard, so I'd take that as a yes.
Related
This question already has answers here:
Replacement for deprecated register keyword C++ 11
(3 answers)
Closed 3 years ago.
In numerical computation in mind, it seems to me that register storage class (which is currently deprecated and removed from the standard) was a good hint for optimization. Was there any specific reason for explicitly removing it from the standard?
Because it is pretty much useless nowadays. register keywords is nothing more then a hint to the compiler that "you should try to give me fast access to this variable". But compilers are much better than you at measuring such things, especially if you're not actually benchmarking your code.
From Wikipedia:
register is essentially meaningless in modern compilers due to optimization which will place variables in a register if appropriate regardless of whether the hint is given
EDIT:
C++ Standard Defect reports
The register keyword serves very little function, offering no more than a hint that a note says is typically ignored. It should be deprecated in this version of the standard, freeing the reserved name up for use in a future standard, much like auto has been re-used this time around for being similarly useless.
In the C++17 filesystem library, we got std::filesystem::remove(path), which — as I understand it — is a direct port of boost::filesystem::remove(path) from Boost.Filesystem.
But C++ inherited from C89 a very similar function called std::remove(path), which is also documented as a way to remove a file from the filesystem. I'm vaguely aware of some pitfalls with this function, e.g. I believe I have heard that on Windows std::remove cannot be used to remove a file that is still being held open by the current process.
Does std::filesystem::remove fix these issues with std::remove? Should I prefer std::filesystem::remove over std::remove? Or is the former just a namespaced synonym for the latter, with the same warts and pitfalls?
The title of my question asks for the difference between boost::filesystem::remove(path) and std::remove(path) because I figure that std::filesystem::remove(path) may not have been implemented by a lot of library vendors yet, but my understanding is that it's supposed to be basically a direct copy of the Boost version. So if you know about Boost.Filesystem on Windows, you probably know enough to answer this question too.
Checking the standard library sources installed with my MSVC, std::experimental::filesystem::remove calls its internal _Unlink helper, which simply calls _wremove, which simply calls Windows DeleteFileW. Similarly, boost::filesystem::remove also just calls DeleteFileW on Windows.
std::filesystem::remove is specified by reference to POSIX remove, but the global wording in [fs.conform.9945] makes clear that implementations are not required to provide the exact POSIX behavior:
Implementations should provide such behavior as it is defined by
POSIX. Implementations shall document any behavior that differs from
the behavior defined by POSIX. Implementations that do not support
exact POSIX behavior should provide behavior as close to POSIX
behavior as is reasonable given the limitations of actual operating
systems and file systems. If an implementation cannot provide any reasonable behavior, the implementation shall report an error as specified in [fs.err.report]. [ Note: [...] ]
Implementations are not required to provide behavior that is not supported by a particular file system. [ Example: [...] ]
Any quirks in ::remove (that is about the actual act of removing rather than identification of the file to be removed) are likely due to limitations of the underlying OS API. I see no reason to think that an implementation of std::filesystem::remove on the same operating system will magically do better.
I was going through the documentation of rand() function in c++ and it says
The function accesses and modifies internal state objects, which may cause data races with concurrent calls to rand or srand. Some libraries provide an alternative function that explicitly avoids this kind of data race: rand_r (non-portable). C++ library implementations are allowed to guarantee no data races for calling this function.
As a more general question how can I be sure that I am calling a c++ implementation of a function (rand in this case)?
Calling rand() inside a file having .cc or .cpp extension.
or, any particular header that can ensure this
I am asking this question because my understanding is that when I use cstdlib header, it in turn calls the c implementation of that (stdlib.h). If that's not case then does c++ provide its own implementation for all c functions?
I think you are asking the wrong question.
You've read that C++ library implementations are allowed to give you a version that has no data races. They are allowed, but they are not required to do so. If you had some all-knowing oracle capable of telling you whether you are using a C++ implementation, and if it told you that you are, would that solve your problem? No, not really, because you still wouldn't know whether that implementation would guarantee the absence of data races. Maybe it would, but you'd have no certainty.
So you have to ask the right question: how do I know whether the function I'm using guarantees that? And the answer is: check the specific documentation of the library you are using! I suppose you are reading the cplusplus.com page on rand. That is a generic site, unrelated to a specific library, so it won't help you answering this question. Instead, what compiler and standard library are you using? Check their documentation. If the authors state that their rand function is guaranteed to be race-free, then go ahead and use it. Otherwise, be conservative and assume there are some races, and don't use it.
And by the way, a lot of people would tell you that that site should be avoided, because it isn't very reliable. In general, cppreference is preferred. And it says that
It is implementation-defined whether rand() is thread-safe.
Where "implementation defined" means exactly what I said. And if you continue reading, it will also list some other problems (the numbers it generates aren't that random after all), and
It is recommended to use C++11's random number generation facilities to replace rand().
I've been searching for a getpass() alternative and it's in fact the simplest way to hide a password input I've founded. It's kind of a loss for C++ here, being such easy function with a lot of use.
What i would like to know is why is it considered obsolete, does it have any security issues ?
And can/should i still use it professionally, disregarding the warnings and taking them as "exaggerated" ?
Why is getpass() considered an obsolete function?
According to this man page
The getpass() function is not threadsafe because it manipulates
global signal state.
The getpass() function is scheduled to be withdrawn from a future version
of the X/Open CAE Specification.
can/should i still use it professionally
If your C library has the function, then you can use it.
If you consider any of: the lack of thread safety, or the manipulation of global signal state in general, or the fact that as an obsolete function it may be removed in a future version of the C library that conforms to a future POSIX version, a problem, then you should not use it.
The recommended alternative is to write your own function, using termios and disable the ECHO flag. Complete minimal substitute in glibc manual.
The term "obsolete" appears to be an add-on from implementers; the actual SUSv2 was less direct:
The return value points to static data whose content may be overwritten by each call.
This function was marked LEGACY since it provides no functionality which a user could not easily implement, and its name is misleading.
The "obsolete" is mentioned in mailing list in 2003 Re: getpass obsolete?, which pointed to an OSF1/Tru63 manual page citing the lack of thread-safe capability, but in regard to the standard at that point in time was only supported by the comments in SUSv2.
Alternative for MFC AfxIsValidAddress in c++ ?
That function actually does not do what it says...
It says that it checks the memory range to see whether it is mapped to the space address of the process. But actually, in most versions of the library, it just checks for a NULL value.
The rationale seems to be that in older versions of Windows, it relied on IsBadReadPtr() and friends. But these functions are totally obsolete, and should not be used in newer code (according to MSDN), thus the change in behavior.
That said, if you want to really check for a memory range, your best option is VirtualQuery().