- Home /
- Visual Studio /
Reported by Daniel Wójcik Nov 17, 2017 at 09:26 AM windows 10.0visual studio 2017 version 15.5 previewfixed in: visual studio 2017 version 15.5.3
Generate C++/CLR console application, in main file (usually ConsoleApplication1.cpp) just after #include "stadafx"
put:
#pragma managed(push, off)
#include <xlocale>
#pragma managed(pop)
and compile this source. Many errors of kind:
1>C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\VC\Tools\MSVC\14.12.25827\include\xlocale(116): error C3821: 'System::Runtime::CompilerServices::RuntimeHelpers': managed type or function cannot be used in an unmanaged function
will be visible in output/error window. VS2017 15.4.4 compiles this without the problem.
This was caused by one of my changes, which removed usage of the extremely fragile non-Standard compiler extension __if_exists from the STL's central internal header yvals.h. I previously believed that __if_exists was unnecessary, but now I see that its answer is sensitive to the presence of this pragma, which we don't test.
Before changing any code here, I'd like to understand why you're using #pragma managed(push, off) - what's causing you to want to wrap the STL's headers in this push-pop?
Thanks,
Stephan T. Lavavej
Principal Software Engineer, Visual C++ Libraries
> Before changing any code here, I'd like to understand why you're using #pragma managed(push, off) - what's causing you to want to wrap the STL's headers in this push-pop?
I can tell you why we wrap the STL headers in a push pop in my codebase. We have managed and unmanaged code. This code interacts, so we may include some unmanaged code in a #pragma unmanaged section. If the unmanaged code happens to #include <string> or <xlocale> and if the managed code happened to not include these headers before including the unmanaged code, we end up in the situation described in that bug.
It's not like we explicitly try to #include <string> from unmanaged sections in managed code, it's that in real life codebases, these situations happen.
I appreciate the desire to clean old cruft from STL headers. I think the real failing here is that your test suite doesn't seem to contain any realistic, medium to large clr project.
Anyway, thanks for the work on coming up with a fix.
> This code interacts, so we may include some unmanaged code in a #pragma unmanaged section.
As far as I can tell, /clr was designed to mix with native code at the translation unit level - which is why MSDN specifically advises against including headers within the pragma.
> I think the real failing here is that your test suite doesn't seem to contain any realistic, medium to large clr project.
Yes, it is a known deficiency. We exhaustively run all of our STL tests under /clr, but this lacks coverage of things that actual CLR codebases do. Usually we're fine anyways because we stick to well-known patterns - I caused this trouble by touching an ancient, special area of code.
In our company we're following to guidance that any native header should be included in managed=off block.
Is there a reason for that "guidance"? Our STL headers are tested extensively under /clr (in a few cases, like mutex, they are outright blocked; anything that isn't blocked is tested), whereas they are not tested within managed=off.
Yes - that was a reason: we had a problems (I don't remember exactly what kind) when native header were not included within managed=off pragma. But in any case - as I understand - it should be not harmful in anyway for the compiler... Or am I wrong?
It's harmful in this case because the preprocessor is identifying the code as managed (because _M_CEE
is defined), but we can't use attributes for managed code (which tell the CLR to pre-JIT the code, to avoid running out of memory at an inconvenient time).
Is this hack acceptable (just temporally till the fix arrives)?:
#pragma unmanaged #undef _M_CEE #include "unmanaged_header.h"
#define _M_CEE 001
#pragma managed
That is "even worse" because the compiler is still in /clr mode but the STL will believe that it isn't. Totally untested and unsupported.
Several of our devs updated to 15.5 today and we've also hit this error. Removing the #pragma managed( push, off ) around our native headers causes numerous warning LNK4248: unresolved typeref token (01000019) for 'NativeClassName'; image may not run. The #undef _M_CEE does not work for us either, it causes numerous other warnings in type_traits.
Can you include STL headers under /clr normally, and then wrap your own headers in the pragma? I will investigate fixing this while still avoiding __if_exists.
Fix for us was moving one of our header includes out of the unmanaged pragma. It took a bit of experimenting, but we got it working in the end. Interestingly, our solution is a huge mix of pure managed, pure native and mixed projects with over 4 million lines of code and we only had a problem with one header in one file, so it isn't likely a widespread problem.
Just installed 15.5.1 today and did a fresh build. It is also dying in xlocale.
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\xlocale(116): error C3821: 'System::Runtime::CompilerServices::RuntimeHelpers': managed type or function cannot be used in an unmanaged function
The macro it is dying on is:
_BEGIN_LOCK(_LOCK_LOCALE)
It also had this error:
error C2668: 'bsearch': ambiguous call to overloaded function
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\ucrt\corecrt_search.h(125): note: could be 'void bsearch(const void ,const void ,::size_t,::size_t,int (__clrcall )(const void ,const void ))'
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\ucrt\corecrt_search.h(45): note: or 'void bsearch(const void ,const void ,::size_t,::size_t,int (__cdecl )(const void ,const void ))'
I am dead in the water. Anyone got a link to instructions on how to roll-back to a previous version of VS?
I've checked in a fix for the xlocale error into our 15.7 branch, and I think I'll request a backport to 15.6. (Backporting to 15.5.x is possible although more difficult; I am not sure if this would meet the 15.6 bar, much less 15.5.x.)
Can you avoid including STL headers within the pragma-managed block? Note that MSDN has always advised against including headers within that pragma.
I haven't seen the bsearch error before - can you provide a self-contained test case for that one (my email address is above)?
As a workaround, we now support side-by-side toolset versions. See https://blogs.msdn.microsoft.com/vcblog/2017/11/15/side-by-side-minor-version-msvc-toolsets-in-visual-studio-2017/ for more info.
Edit: I can reproduce the bsearch error, without a pragma managed block, if I pass a stateless lambda (which is "omniconvertible" in VC's implementation to function pointers with arbitrary calling conventions). Passing an ordinary function works fine. I'm not sure why this would have changed between 15.4 and 15.5, and it is not related to the xlocale error.
Thanks for the link! My usage scenario is I have a giant C++ library used by many EXEs. I want to expose some of this functionality to .Net. I created a managed C++ project that functions as an adapter. The managed C++ does nothing other than translate data from managed to native, call the native, return back to .Net. The native code has lots of inline functions which is why the bsearch() failed to compile. What solved my problem (until 15.7) was undef'ing _M_CEE before including the giant C++ library's header file. The way my headers work is the precompiled header (stdafx.h) includes only the C++ library. The individual .cpp files then include the managed C++ specific header files. Here's my stdafx.h
#pragma unmanaged
#undef _M_CEE
#include <truxton.h>
#define _M_CEE 001
#pragma once
The managed C++ header files use #pragma managed to make sure native isn't compiled.
So far, it has passed unit, application and integration testing. Will keep an eye on it though.....
Thank you for your feedback! We have fixed the problem in an upcoming release. Thank you for helping us build a better Visual Studio!
Added a solution by Pierre Chevalier · Dec 13, 2017 at 10:40 AM
For anyone reading and looking for a workaround, a way to make sure that the STL headers are not included in unmanaged sections of managed code is to explicitly include them before the #pragma unmanaged or #pragma managed(push, off) line. You may then rely on their header guards for preventing their content from actually being included.
For instance:
#pragma unmanaged #include <string> #pragma managedwould fail.
But
#include <string> // This one is fine: including header in managed section of the code // The macros (_MANAGED, _M_CEE, ...) are consistent #pragma unmanagedwould workaround the issue.
#include <string> // This one does nothing. Yay, header guards! #pragma managed
Added a solution by Blair Wang-MSFT · Jan 10 at 01:25 AM
This issue has been fixed and is now available in our latest update. You can download the update via the in-product notification or from here: https://www.visualstudio.com/vs/ Thanks to everyone who provided feedback, votes and solutions for this problem.
Added a solution by Ferdinand Oeinck · Dec 12, 2017 at 03:35 PM
[Oeps, no solution... More problems]
I removed #include <string> out of the #pragma unmanaged to resolve xlocale problem.
But my project generates a 'partially trusted application' see: https://msdn.microsoft.com/en-us/library/ms235238.aspx
So I link with ptrustm.lib in stead of msvcmrt.lib, which leads then to these linker errors:
error LNK2028: unresolved token (0A0008A6) "void __clrcall eh vector destructor iterator'(void *,unsigned int,unsigned int,void (__clrcall*)(void *))" (??_M@$$FYMXPAXIIP6MX0@Z@Z) referenced in function "public: virtual void * __thiscall std::exception::
vector deleting destructor'(unsigned int)" (??Eexception@std@@$$FUAEPAXI@Z)
1>ManagedGrids.obj : error LNK2019: unresolved external symbol "void _clrcall eh vector destructor iterator'(void *,unsigned int,unsigned int,void (__clrcall*)(void *))" (??_M@$$FYMXPAXIIP6MX0@Z@Z) referenced in function "public: virtual void * __thiscall std::exception::
vector deleting destructor'(unsigned int)" (??_Eexception@std@@$$FUAEPAXI@Z)
VS Hanging
1
Solution
CMake: Ninja project defaults to Clang compiler instead of VC14
1
Solution
Visual Studio 2017 15.5 Preview 2 breaks C# 7.2 support
1
Solution
expression did not evaluate to a function in vector
0
Solution
VS15.5 Preview 5 crashes with stackalloc + ref struct
0
Solution
"Symbol loading" dialog disappears or is hidden behind VS
0
Solution
fatal error C1001 [crash] involving std::forward, if constexpr, and variable function templates
1
Solution
powershell interactive window focus leaves after executing command
1
Solution
'Pack project' command does not work when project build result is up-to-date
2
Solution