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().
Related
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'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.
Can a std::string be passed by value across DLL boundries between DLLs built with different version of Visual Studio?
No, because templated code is generated separately per module.
So, when your EXE instantiates a std::string and passes it to the DLL, the DLL will begin using a completely different implementation on it. The result is a total mess, but it often sorta almost works because implementations are very similar, or the mess is hard to detect because it's some kind of subtle heap corruption.
Even if they're both built with the same version of VS, it's very precarious / fragile, and I would not recommend it. Either use a C-style interface between modules (for example, COM), or just don't use a DLL.
More detailed explanation here: Creating c++ DLL without static methods
and here: How can I call a function of a C++ DLL that accepts a parameter of type stringstream from C#?
In general, you can not mix binary code built with different compilers, which includes different versions of the same compiler (and can even include the same compiler invoked with different commandline options), so the answer to what you are trying to do is a clear "No".
The reason is that different compilers might provide different implementations of std::string. For example, one implementation could have a fixed, static buffer, while another version doesn't, which already leads to different object sizes. There is a bunch of other things that can make the interfaces incompatible, like the underlying allocator, the internal representation. Some things will already fail to link, due to name mangling or different private APIs, which both protect you from doing something wrong.
Some notes:
Even if you didn't pass the object by value but by reference, the called code could have a different idea of what this objects looks like.
It also doesn't matter that the type is supplied by the compiler, even if you defined the class yourself and compiled two DLLs with different versions of the class definition you would have problems. Also, if you change your standard library implementation, you make your binaries incompatible, too.
It doesn't even matter that the other code is in a DLL, it also applies to code in the same executable or DLL, although headers and automatic recompilation on change make this case very unlikely.
Specifically for MS Windows, you also have a debug heap and a release heap, and memory allocated in one must not be returned to the other. For that reason, you often have two DLL, one with a 'd' suffix (the debug version) and one without. This is a case where the compiler settings already affect compatibility, but you can get around this using a parallel approach of providing two versions of your DLL, too.
To some degree, similar problems occur for C code, too, where compilers have to agree on e.g. struct layout and calling conventions. Due to greater age and lower complexity, different C compilers are effectively compatible though. This is also accepted as a necessary feature in C as opposed to C++.
The C++ standard 3.6.3 states
Destructors for initialized objects of static duration are called as a result of returning from main and as a result of calling exit
On windows you have FreeLibrary and linux you have dlclose to unload a dynamically linked library. And you can call these functions before returning from main.
A side effect of unloading a shared library is that all destructors for static objects defined in the library are run.
Does this mean it violates the C++ standard as these destructors have been run prematurely ?
It's a meaningless question. The C++ standard doesn't say what dlclose does or should do.
If the standard were to include a specification for dlclose, it would certainly point out that dlclose is an exception to 3.6.3. So then 3.6.3 wouldn't be violated because it would be a documented exception. But we can't know that, since it doesn't cover it.
What effect dlclose has on the guarantees in the C++ standard is simply outside the scope of that standard. Nothing dlclose can do can violate the C++ standard because the standard says nothing about it.
(If this were to happen without the program doing anything specific to invoke it, then you would have a reasonable argument that the standard is being violated.)
Parapura, it may be helpful to keep in mind that the C++ standard is a language definition that imposes constraints on how the compiler converts source code into object code.
The standard does not impose constraints on the operating system, hardware, or anything else.
If a user powers off his machine, is that a violation of the C++ standard? Of course not. Does the standard need to say "unless the user powers off the device" as an "exception" to every rule? That would be silly.
Similarly, if an operating system kills a process or forces the freeing of some system resources, or even allows a third party program to clobber your data structures -- this is not a violation of the C++ standard. It may well be a bug in the OS, but the C++ language definition remains intact.
The standard is only binding on compilers, and forces the resulting executable code to have certain properties. Nevertheless, it does not bind runtime behavior, which is why we spend so much time on exception handling.
I'm taking this to be a bit of an open-ended question.
I'd say it's like this: The standard only defines what a program is. And a program (a "hosted" one, I should add) is a collection of compiled and linked translation units that has a unique main entry point.
A shared library has no such thing, so it doesn't even constitute a "program" in the sense of the standard. It's just a bunch of linked executable code without any sort of "flow". If you use load-time linking, the library becomes part of the program, and all is as expected. But if you use runtime linking, the situation is different.
Therefore, you may like to view it like this: global variables in the runtime-linked shared object are essentially dynamic objects which are constructed by the dynamic loader, and which are destroyed when the library is unloaded. The fact that those objects are declared like global objects doesn't change that, since the objects aren't part of a "program" at that point.
They are only run prematurely if you go to great effort to do so - the default behavior is standard conforming.
If it does violate the standard, who is the violator? The C++ compiler cannot be considered the violator (since things are being loaded dynamically via a library call); thus it must the the vendor of the dynamic loading functionality, aka the OS vendor. Are OS vendors bound by the C++ standard when designing their systems? That definitely seems to be outside of the scope of the standard.
Or for another perspective, consider the library itself to be a separate program providing some sort of service. When this program is terminated (by whatever means the library is unloaded) then all associated service objects should disappear as well, static or not.
This is just one of the tons and tons of platform-specific "extensions" (for a target compiler, architecture, OS, etc) that are available. All of which "violate" the standard in all sorts of ways. But there is only one expected consequence for deviating from standard C++: you aren't portable anymore. (Unless you do a lot of #ifdef or something, but still, that particular code is locked in to that platform).
Since there is currently no standard/cross-platform notion of libraries, if you want the feature, you have to either not use it or re-implement it per-platform. Since similar things are appearing on most platforms, maybe the standard will one day find a clean way to abstract them so that the standard covers them. The advantage will be a cross-platform solution and it will simplify cross platform code.
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.