How to restore auto_ptr in Visual Studio C++17 - visual-studio-2017

This blog page mentions that Visual Studio removes some std features:
https://blogs.msdn.microsoft.com/vcblog/2017/12/08/c17-feature-removals-and-deprecations/
I have a project that consumes some C++ libraries that now use C++17 features. The project also consumes a third party library websocketpp (https://github.com/zaphoyd/websocketpp) that still uses some now removed features. eg auto_ptr and binary_function. I'm getting compiler errors that they are not a member of 'std'.
The blog above mentions that removed features can be restored using a fine grain control. I'm thinking I could use that to get this project to compile for now. Longer term I will see about upgrading websocketpp to C++17 or replacing it with something else.
But, what is the magic to restore features? Is there something I need to #define? If so, what?

In VS2017 v15.5 it is conditionally excluded, based on the project's /std:c++17 setting. You can force it to be included by forcing the underlying macro value. Two basic ways to do this:
Project > Properties > C/C++ > Preprocessor > Preprocessor Definitions and add _HAS_AUTO_PTR_ETC=1. Do so for all configurations and platforms.
If you use a precompiled header then you probably favor defining the macro there. Before any #includes, insert #define _HAS_AUTO_PTR_ETC 1.
Beware of the "ETC", you'll also slurp the deprecated random_shuffle() and unary_function<>. Predicting the future is difficult, but this is probably going to work for a while to come.

Related

How to use The highest Warning Level (Wall) for Visual Studio 2017 when it's incompatible for the std headers?

But I want to use it with "Warnings treated as errors" = Yes
There seems to be a lot of useful check in the compiler flag but it isn't compatible with the standard headers. I want to use this compiler flag to check my code, but not the std headers. Is there a way to do this?
Or just disable warnings for any code I didn't write?
Edit:
Added pictures of the settings in visual studio and an example of what happens when I try to build. With just including iostream!
Example when trying to compile a basic C++ program with these settings
You can disable the warnings in the headers (or change warning level for them) by changing the warning level before each inclusion, see here: How to suppress warnings in external headers in Visual C++. However that is not so handy because it needs to be done for every inclusion.
However if you'd use precompiled headers (which might be actually good for compilation speed), you can put all the system/STL headers you care about into the precompiled header file, and disable them via pragmas just there. Or you would need to create wrappers for the standard headers where you'll disable the warnings and include the wrapper headers instead.
And as discussed, the "/Wall" sometimes goes too far (e.g. the padding is quite usual thing you sometimes even can't do anything about), and even with the "/W4" the documentation mentions that it might be too detailed (however at the same time recommends it for new projects, so I generally use "/W4 /WX" for new projects). However some of the "/Wall" warnings still might find subtle bugs (like missing case in switch etc.). You might as well enable just some of the extra warnings selectively.

Selectively disable C++ Core Guidelines Checker for third party libraries

I would like to try to use the Core Guidelines checker tool on a C++11/14 project, under VS2015.
In my code I use many libraries from Boost which trigger a lot of warning. I am not concerned by those warnings, since Boost is doing a lot of very clever work and the libraries were not written with the aim of conforming to the Guidelines, which they mostly predate.
But with such a flood of warnings I am unable to find out the real issues (at least according to the tool) in my code.
Is there a way to suppress all the warnings for third party code? Maybe there is some attribute before and after #including boost headers?
I have read this page from the Visual C++ Team blog but I have been unable to find it.
There's an undocumented environment variable, CAExcludePath, that filters warnings from files in that path. I usually run with %CAExcludePath% set to %Include%.
You can also use it from MSBuild, see here for an example (with mixed success): Suppress warnings for external headers in VS2017 Code Analysis
MSVC is working on something similar to GCC's system headers that should be a more comprehensive solution to this problem.
Currently, in VS, the feature to suppress warnings from third-party libraries are still experimental but certainly coming.
VS 2017 version 15.6 Preview 1 comes with a feature to suppress warnings from third-party libraries. In the following article, they use "external headers" as a term to refer to the headers from third-party libraries.
https://blogs.msdn.microsoft.com/vcblog/2017/12/13/broken-warnings-theory/
The above article basically says that
specify external headers
specify warning level for external headers
to suppress warnings from them. For example, if we have external headers in some_lib_dir directory and want to compile our code in my_prog.cpp which depends on the external headers, the following command should do the job.
cl.exe /experimental:external /external:I some_lib_dir /external:W0 /W4 my_prog.cpp
Note that /experimental:external is required because this is still an experimental feature, and the details of this feature may change in the future.
Anyway, we need to wait for the future release of Visual Studio.

C++ Using features of a newer compiler to generate code for use by an older compiler

I've been looking into some of the features of the "newer" C++ standards (C++11 and C++14), and that got me thinking about something. I'm currently using the VC++2008 compiler for my projects (for various reasons), which means that the newest standard I have access to is C++03, plus TR1. TR1 has some nice things in it, but there are features in C++11 and C++14 that would be nice to have.
My question is this: Would there be any way that I could build some code using a newer compiler (say MSVC2012 or 2013) to build libraries or DLLs using the newer C++11 and C++14 functionality and then link that into my project that's running the '08 compiler?
The only thing that I could think of that wouldn't work would be anywhere I had to have a C++11 or C++14 feature in a header included by my '08 compiler project. However as long as everything "new" were hidden behind my interface, shouldn't this work?
Yes but its going to get ugly.. since the ABI is not compatible you'll have to go down to the "extern "C" {}" ABIness.
That means you can't pass C++ objects at all.. like I said, painful. It also means it must be a DLL since you won't be able to link in a static lib with another ABI.
Its up to you if its worth wrapping up a DLL in a C API just to use a couple of new features or not, I would recommend just upgraded the whole project though.
I almost forgot, you probably can't link the import lib either, so you'll have to have some code that uses LoadLibrary, GetProcAddress and FreeLibrary (did I mention this is ugly/painful?).
Unfortunately, what you're trying to do is not possible with MSVC. They intentionally break binary compatibility with every major release as stated in MSDN documentation:
To enable new optimizations and debugging checks, the Visual Studio implementation of the C++ Standard Library intentionally breaks binary compatibility from one version to the next. Therefore, when the C++ Standard Library is used, object files and static libraries that are compiled by using different versions can't be mixed in one binary (EXE or DLL), and C++ Standard Library objects can't be passed between binaries that are compiled by using different versions. Such mixing emits linker errors about _MSC_VER mismatches. (_MSC_VER is the macro that contains the compiler's major version—for example, 1800 for Visual C++ in Visual Studio 2013.) This check cannot detect DLL mixing, and cannot detect mixing that involves Visual C++ 2008 or earlier.
Your options are to then only pass around POD types, or implement COM interfaces to interop between the DLLs compiled using different version of the VC compiler, neither of which is particularly palatable.
My advice would be, if you must stick with VS2008 for certain legacy applications, suck it up and deal with the feature set it supports (at least you have TR1). For newer projects, try and talk your team into using newer versions of VC.

LNK2038, iterator mismatch error, need to ignore

I'm getting the linker error LNK2038 when trying to convert a VS2008 project to VS2010. This error occurs when two different projects are compiled in which one is using _DEBUG preprocessor macro, and the other is not. Basically I have a 3rd party library that only has release .libs, so when I try and use that library when building my project in debug mode I get this mismatch.
I understand why Microsoft is giving this error (STL iterator safety), however our project does not use Microsoft's STL, we use STLPort, so this error means nothing to our project. I just need a way to prevent it from doing this check.
Inside of the STL includes there is a file called yvals.h, which includes the #pragma detect_mismatch definition for the various _ITERATOR_DEBUG_LEVEL settings. That set of definitions is wrapped in an #ifndef _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH, #endif. However, even if I define _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH as a preprocessor macro for my entire project I'm still getting the same linker error. I can even alter yvals.h to define that macro and it does nothing (I'm assuming because the STL itself would need to be recompiled).
So my question is basically, what steps can I take make _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH actually work as intended so that my project doesn't do this check anywhere when compiling in VS2010?
EDIT: I know this is a late response but I just found this post and realized I didn't post the solution. As others mentioned there was a mismatch in the libraries. As it turns out VS2010 changes the default directories for certain projects (I found a thread on MSDN at one point full of complaints about it), and that directory change had caused VS2010 to look in the wrong directory for the debug library, and it was finding the release library instead.
You must use the same version of the standard library, compiled with the
same options, if you expect to successfully link. If you use STLPort,
then you can only link with libraries which use the STLPort, not with
libraries which use the VC++ standard implementation. If you mix,
either you will fail to link, or you will get strange runtime errors.
The problem is that things like std::vector<>::iterator may be defined
completely differently; depending on where and how they are used, you
will find yourself using an instance constructed in a different library,
with a different layout.

VC++ replaces defines of different objects, GCC etc. not

I have a big app using many static libs, which is platform independant and deployed under Windows and Linux.
All static libs and the main() itself are compiled with two defines:
-DVERSION=1.0.0 -DBUILD_DATE=00.00.0000
These defines are used by macros inside each static lib and inside the main to store the current lib version inside a registry-like class.
Under GCC / Linux this works very well - you can list all linked modules and display their real version and builddate, e.g.:
ImageReader 0.5.4 (12.01.2010)
Compress 1.0.1 (03.01.2010)
SQLReader 0.3.3 (22.12.2009)
But: When I link the exactly same code with VisualStudio 2005 SP1 I get only the version and build date of the last compiled module:
ImageReader 0.5.4 (12.01.2010)
Compress 0.5.4 (12.01.2010)
SQLReader 0.5.4 (12.01.2010)
Has anybody an idea? Is this an "optimization" issue of the VC++ linker?
Well, Visual Studio supports solutions with multiple projects. And its dependency engine is capable of detecting that a changed macro value requires a project to be recompiled. Occam's razor says that the libs simply got rebuilt and acquired the new VERSION macro value.
Preprocessor defines are resolved by the preprocessor stage of the compiler, not the linker.
There could be an issue with precompiled headers though in VC++.
Otherwise, to really tell I'd like to see the source code doing the actual printing of the version (date).
This doesn't have anything to do with the Visual Studio linker; it's just a matter of preprocessor macros, so the problem is already at the very beginning, before the compiler even gets to work.
What does the compile line look like in your Visual Studio build? My first idea is that for some reason, the defines (-D arguments) are all added to a single command line, and the last one always wins.
I'm assuming you have an app which then links to these libraries, and it's in this app that you're seeing the identical version numbers.
Make sure that the app doesn't have these -D switches as well. If not, then my guess is that VC compiler is being clever and triggering a build of the dependent projects with the same -D switch, rather than triggering the build via the project file.
Also, the best way to version these binaries is by employing macros in headers/source directly and giving them all unique names for each library. That way they can't interfere with each other (unless you clone one of the headers into an app, duplicating the Macro defs), and you're no longer dependent on the compiler to do it properly.
This can be a issue if you are using pre-compiled headers. Try building the application by disabling pre-compiled headers option.
"These defines are used by macros inside each static lib and inside the main to store the current lib version inside a registry-like class."
You're not violating the One Definition Rule by any chance? If you have one class, it should have one definition across all libraries. it sounds like the class definition depends on a version macro, that macro is defined differently in different part of your program, and thus you violate the ODR. The penalty for that is Undefined Behavior.
It seems that the MS linker takes advantage of the ODR by ignoring everything but the first definition. After all, if all definitions of X are the same, then you can ignore all but the first.