I start a C++ Project that uses the "Visual Studio 2017 - Windows XP (v141_xp)" Platform Toolset
Set Runtime Library to "Multi-Threaded (/MT)"
Change "Debug" to "Release"
Add #include "<Wbemidl.h>" to the source.
CTRL F5 (aka Build)
Now, I am aware that platform set is deprecated but, either way, the default x64 build has no issues. However, when I change to "x86" from "x64" (as that's what I want), it then produces numerous errors like the following:
C++ 'default argument': cannot convert from 'const wchar_t' to 'BSTR'
You might ask what am I trying to do? Maybe some of my code is bad? You should not convert wchar_t to BSTR as it is not defined what will be the result?
But these aren;t my concerns, here. I didn't add any code – just the single header include (I left the "Hello World" part).
I didn't explicitly convert anything as the error is in the Microsoft system headers, not in my Code. I didn't add anything to do with QT nor do I need or want QT so that's not the issue.
I just for now want to compile my "Hello World" Program using the <Wbemidl.h> header. (Of course, I don't need that header to compile it but, if I can compile it without issues, I most likely then can use the library without issues.) I wanted to make this as simple as possible, hence why it just is "Hello World" (a MCVE).
I tried adding the following but without success:
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "wbemuuid.lib")
My best guess is that I didn't install something and or its just deprecated; the funny thing is "2015 Visual Studio (140_xp)" works.
I just want to compile my C++ "Hello World" Program with the Header "<Wbemidl.h>" , Compiled in "x86", Toolset of "Visual Studio 2017 - Windows XP (v141_xp)" and Runtime Library as "Multi-Threaded (/MT)"
My code (MCVE):
#include <iostream>
#include <Wbemidl.h>
int main()
{
std::cout << "Hello World!\n";
}
Microsofts Code ERROR
Other things I tried:
Strict QT strings tags
Including other stuff
Changing from "Multi-Threaded (/MT)" to "Multi-threaded DLL (/MD)"
Tried making 4 Different projects
Since (IIRC) VS 2019 (and certainly for VS 2022), there is a C++ compiler setting that (by default) forces much stricter adherence to the language standard. That setting ("Conformance Mode") will prevent the conversion (const w_char[] to BSTR) that is being used in the (older) SDK header files.
This option was already present in VS 2017 but was disabled by default; in VS 2015 (which, you say, works without the errors), the option is simply not present. Thus, when you change the toolset from VS 2022 to VS 2017, you are (unwittingly) enabling that "conformance mode" option.
To disable these errors, you need to turn off conformance mode. In your project settings, go to the "C/C++" … "Language" property page and set "Conformance Mode" to "No":
There will very likely still be numerous other warnings but the system headers will, at least, compile without errors.
Note that, when using the newer toolsets, the MSVC compiler uses system header files from a newer SDK; in those headers, the issues have been properly addressed, so conformance mode can be used.
Related
These two trivial lines of code:
const bool equal = (HUGE_VALF == HUGE_VALF);
static_assert(equal == true, "Fatal error");
in a test program work perfectly (no warnings and no errors).
When I copy them in the main project, I get this error on the assert:
error C2057: expected constant expression
Here the equal object is a constant with value = true.
Those lines of code are in both cases inside functions.
The two projects have identical settings (C++11, Visual C++ 2013 compiler, Visual C++ 2019 IDE, /W4, no optimizations).
What could be the reason of this different behaviour from the compiler?
When a newer Visual Studio IDE (like VS 2019) loads an older project for the first time, it asks to retarget the project. If You have the old Visual Studio installed, You can reject this action. Then the compiler from the original VS will be used by the newer IDE.
After loading the solution, in the Solution Explorer next to the project name, You will have the Visual Studio which will be used to compile the project.
If the paranthesis is missing, that means the compiler and standard library from the current Visual Studio is been used.
As mentioned in the comments:
I have no parenthesis after the project name (if I am looking in the right place). However, I realised about the issue in the include file paths: Test Project: 14.24.28314\include\cmath; Main Project: Microsoft Visual Studio 12.0\VC\include\cmath, i.e. a much older version, that internally still relies on the C math.h header. So, same compiler (VS2013), different libraries...
This indicates that You have most probably retargeted the project or created a new project in VS 2019.
To make a project in VS 2019 make use of the older compiler, You need to got to the project Properties -> Configuration Properties -> General -> Platform Toolset and change it to the appropriate Visual Studio.
Also make sure that all configurations (Debug, Release,...) for all machine types (32bit, 64 bit) have this setting the same value.
Because the test project is using VS 2019 - it has all the required definitions - so it works.
So the issue is that most probably, VS 2013 standard library is not C++11 complete and does NOT have a definition for HUGE_VALF.
But it could contain a definition for HUGE_VAL
It looks like std::string is a header only file at Community/VC/Tools/MSVC/?/include/xstring, and all generated code should be included inside a build target.
If I'm correct, how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?
Update 1:
I got many downvotes for this question so let me explain why I decided to ask it.
I'm faced with strange crash, and I can not understand why this happen.
I use latest Qt 5.13.0 (MSVC2017_x64) and also I have some external libraries compiled with Visual Studio 2017. All have /MDd, I checked this with dumpbin util.
When I try to run any code that invokes Qt library and std::string, I'm getting wrong result (and crash at the end).
Here is very simple example:
#include <QApplication.h>
int main(int argc, char** argv) {
QString s1("Test");
std::string s2 = s1.toStdString(); // here we have s2 variable with wrong internal structure
return 0;
}
My idea was that QtCore DLL library has std::string with internal structure not compatible with std::string from Visual Studio 2017. But Qt was created with Visual Studio 2017 (maybe not same as my current Visual Studio, because there was several minor releases), so I decided to ask here if they are compatible or not.
Update 2:
Problem was in _ITERATOR_DEBUG_LEVEL. Looks like Qt was compiled with level 2 and all my external libraries and application were compiled with level 0.
This option affects internal structure of many C++ standard library classes and introduce such side effects. So when we are inside toStdString() and create std::string, we have level 2 and one internal structure. When we are in application code, we have level 0 and another internal structure. We assign object with one internal structure to object with another.
Anyway now I have better understanding of some internals.
how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?
Because they make a decision to guarantee that, or to not guarantee that.
For example, Visual Studio 2015 to 2019 are binary compatible.
That's a decision that was made, to do that. The result, if what you say is true, is that some of the implementation specifics of std::string on that platform are frozen. This is not unusual for libraries. libstdc++'s std::list::size was non-compliant to C++11 for many years, because they could not add a needed member variable without breaking binary compatibility.
In short, this is basically a project management decision, and if they ever change the header in a way that breaks things, they will tell you that binary compatibility has been broken and you need to rebuild and relink things accordingly.
As for your Qt issue, it does smell like a binary compatibility issue. But you say that both Qt and your application have been built in Visual Studio 2017 with /MDd, which would appear to rule that out. I would ask the Qt community for further help, possibly with slightly more information about your environment and about where you obtained Qt. Also ensure that you're using the version of Qt that's intended — perhaps there are multiple installations? Which one's on your include path?
Is std::string header only in Visual Studio?
Not entirely, it also depends on parts of the Standard C++ library that are implemented in Microsoft's Visual C++ Runtime. Building a binary with MSVC requires the VC++ runtimes to be linked. Only static libraries may be built without linking to a runtime, and then you must be careful to include none of the headers that require the runtime.
Is the std::string header only in Visual Studio?
(I originally read the headline this way.)
std::string is part of the C++ standard.
To use std::string on any platform that supports standard C++, you should use #include <string>. It is a standard header available with pretty much any C++ compiler.
Every compiler or platform may implement the standard in its own way though. For example with MSVC you can see that xstring is how Microsoft implements std::string under the hood. If you include xstring.h directly you are writing code that depends on the version of MSVC that provides that header. That code would not be portable to other compilers.
If I'm correct, how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?
Microsoft does not guarantee that the next Visual Studio version will have the same std::string internal structure. In the past the implementation of the standard library has changed with every VC++ runtime release, which is why Windows users end up having dozens of VC++ runtime versions installed in their Add/Remove programs list.
Thankfully Microsoft has given us a guarantee that Visual Studio 2015, 2017, and 2019 all use a binary-compatible C++ runtime. This means that binaries built using the standard library provided in Visual Studio 2015 are compatible with binaries built using 2017 and 2019 too. There is no guarantee (yet) that a future version of Visual Studio will not change the VC++ runtime implemenation again.
I have also posted this on the MSDN forum here: MSDN Forum Post
When using the /clr option with a Visual Studio C++ project, the debug visualizer for std::string and other types don't seem to be working. Here are the steps:
Launch VS2012 or 2013
Create a new Visual C++ / Win32 Console Application
In the main .CPP file, add: #include <string>
In the main method, add: std::string s = "abc";
Debug the program and inspect the variable 's'. Notice how it shows the string "abc". This is what we want.
Open the project properties / General. Set "Common Language Runtime Support" = "Common Language Runtime Support (/clr)"
Debug the program and inspect the variable 's'. Now the string "abc" does not appear.
Further info:
I can see debug visualizer definitions for std::basic_string in both the autoexp.dat and stl.natvis files for Visual Studio. However it appears to be ignoring these when /clr is used. One way I'm confirming that it's actually ignoring these definitions is by putting extra text in them. When /clr is not used, VS shows the text in preview; with /clr on, it does not.
There are other similar threads about this such as:
Visual Studio 2013 C++: STL container's elements display in debugger
Other links in the MSDN post; stackoverflow won't let me post more yet.
However, all of these threads seems to indicate that autoexp.dat and/or natvis files are used and can be modified. In my case, I believe these files are being completely ignored when /clr is used.
Does anyone know of a work-around?
Is there a (Microsoft-specific) CPP macro to determine when I'm using the VC9 compiler in Visual Studio 2010 as opposed to Visual Studio 2008? _MSC_VER returns the compiler version, so with VS2010 multi-targeting feature, I'll get the same result as with VS2008.
The reason for wanting to know the difference is that I created a new VS2010 project which contains code removed from a larger project. I just left the VS2008 stuff "as is" since we're moving away from VS2008 "soon" anyway and I didn't want to go through the hassle of creating a vcproj file along with the new vcxproj.
For now, I've just defined my own macro to indicate whether the code is compiled into its own DLL or not; it works just fine, but it would be nice if there were something slightly more elegant.
_MSC_VER returns the compiler version
It sounds like that's what you really do want (or am I misunderstanding?).
If the compiler from VS2008 (which confusingly is also known as VC9 or cl.exe 15.0) is being used, then _MSC_VER will return a value that's greater than or equal to 1500. If the compiler from VS2010 is used (also known as VC10 or cl.exe 16.0), then _MSV_VER will evaluate to 1600.
It seems there is no solution, a custom macro works even if it isn't quite as elegant as I would like.
I'm running Windows 7 and Visual Studio 2008 Pro and trying to get my application to work on Windows XP SP3.
It's a really minimal command line program so should have any ridiculous dependencies:
// XPBuild.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
printf("Hello world");
getchar();
return 0;
}
I read somewhere that defining several constants such as WINVER should allow me to compile for other platforms. I've tried the added the following to my /D compiler options:
;WINVER=0x0501;_WIN32_WINNT 0x0501;NTDDI_VERSION=NTDDI_WINXP
But that made no difference. When I run it on my Windows XP machine (actually running in a virtualbox) I get the following error:
This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.
So what have I missed? Is there something else required to run MSVC compiled programs or a different compiler option or something else?
What you have missed is most likely that VC++ programs require a runtime to be installed (unless you link statically, which is not the default) - the error message you show is exactly the one you get if they're not in order.
Try installing the Microsoft Visual C++ 2008 SP1 Redistributable Pack on the XP machine - you will most likely see that your program works with no changes whatsoever.
Michael's answer explains why it doesn't work for you, and what you should do about it. With respect to WINVER - they don't change anything about your binary in a sense that it would suddenly start working on XP. What they do is disable function and type declarations in Windows headers files that are not supported on the OS version specified by WINVER. This ensures that you do not accidentally call e.g. some Vista-only function. However, you don't strictly need it - if your code does not rely on any Vista/7-only functionality, you can compile without redefining WINVER, and it'll still work fine on XP.
Just Set the compiler to use static linking in the project settings (Project -> Properties -> Config Properties -> C/C++ -> Code Generation -> Change "Runtime Library" to /MT or /MTd instead of the default /MD or /MDd)