Forgottenserver: VS 2015 Update 2

Created on 4 Apr 2016  ·  14Comments  ·  Source: otland/forgottenserver

Visual Studio 2015 Update 2 causes this compile-time error:

Error C2338 You've instantiated std::atomic with sizeof(T) equal to 2/4/8 and alignof(T) < sizeof(T). Before VS 2015 Update 2, this would have misbehaved at runtime. VS 2015 Update 2 was fixed to handle this correctly, but the fix inherently changes layout and breaks binary compatibility. Please define _ENABLE_ATOMIC_ALIGNMENT_FIX to acknowledge that you understand this, and that everything you're linking has been compiled with VS 2015 Update 2 (or later). (compiling source file ..\src\outputmessage.cpp) theforgottenserver C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\atomic 661

bug

Most helpful comment

The issues comes from the fact that we use boost::lockfree::stack and not the ThreadState enum. Boost.Lockfree is a header-only library, so upgrading to VS2015.2 should be sufficient.

All 14 comments

Did you try to define _ENABLE_ATOMIC_ALIGNMENT_FIX ?

Since it may misbehave in older versions than VS2015 Update 2, this should be fixed rather than acknowledged just to bypass the error.

In enums.h, please try changing:

enum ThreadState {

to:

enum ThreadState : uint8_t {

If that solves it, please also submit a pull request.

Here I am having the same problem , however put enum ThreadState : { uint8_t
and still the same error.

Is it the exact same error? With uint8_t, sizeof(T) should be 1, so that's weird. Any ideas, @djarek?

I think the issue here is that alignof(uint8_t)==1 which means that the variable can be placed at any address and atomic instructions usually require an aligned memory access. TBH I'm surprised MSVC doesn't choose the proper alignment for the atomic variable by itself.

@guilhermesidney
Could you check this instead:

enum ThreadState : uint64_t {

@djarek
Still the same error is no problem with this update 2 Visual Studio ??

Why not trying to compile build using Cmake?

Why not trying to compile using Cmake ?

Cmake is not a compiler

Sorry, missed it,
Meant "using MinGW compilers, and managing the build with CMAKE".

I dont know if this will help in some way, but i found this link at Microsoft helping:

https://connect.microsoft.com/VisualStudio/feedback/details/1892487/code-generated-by-msvc-doesnt-operate-atomically-on-std-atomic-t-object-when-sizeof-t-n-alignof-t-n-n-2-4-8

Its looks like that this thread generated the update that is making this error of compiling exists now in VS 2015 Update 2.

If @marksamman can analysis from where it cames i think that he can fix it.

*EDIT:

I also found this out on the development blog of Microsoft https://blogs.msdn.microsoft.com/vcblog/2016/04/14/stl-fixes-in-vs-2015-update-2/

  • : I fixed a subtle-but-nasty silent bad codegen bug affecting atomic (VSO#152725/Connect#1892487). If you were triggering the atomic bug, you’ll be greeted by a static_assert when upgrading, where I explain what’s happening: “You’ve instantiated std::atomic with sizeof(T) equal to 2/4/8 and alignof(T) < sizeof(T). Before VS 2015 Update 2, this would have misbehaved at runtime. VS 2015 Update 2 was fixed to handle this correctly, but the fix inherently changes layout and breaks binary compatibility. Please define _ENABLE_ATOMIC_ALIGNMENT_FIX to acknowledge that you understand this, and that everything you’re linking has been compiled with VS 2015 Update 2 (or later).”

There’s a related bug with atomic on x86, where things are weird because the stack is only 4-aligned. Examples of SizeEightAlignEight types are: long long, double, StructWrappingLongLong, and StructWrappingDouble. During layout, the compiler has always treated these types as 8-aligned, so struct Outer { char c; SizeEightAlignEight meow; }; contains 7 bytes of padding. However, the compiler doesn’t always emit code to dynamically align the stack, so SizeEightAlignEight variables can appear on the stack at 4-byte boundaries. (This is intentional – dynamic alignment has a nonzero cost, and x86 doesn’t need long longs and doubles to be on 8-byte boundaries for correctness. Sometimes 8-byte boundaries can improve performance, so the compiler has heuristics to determine when dynamic alignment would be beneficial.)

Before Update 2, this also applied to atomic – it participated in layout with 8-alignment, but didn’t trigger dynamic alignment on the stack. This was bad, because it needs to live on 8-byte boundaries for correctness. In Update 2, this has been partially fixed. atomic, atomic, and atomic now have data members marked with alignas(8). This means that their layout is unchanged (so they don’t trigger the static_assert message mentioned above), but they now trigger dynamic stack alignment for correctness.

Unfortunately, I didn’t realize until just now that atomic (and atomic) were affected, and weren’t fixed in Update 2. This is because atomic specializations exist to provide integral operators, and my alignas fix affected only atomic (which is also used by atomic even though double isn’t a UDT). I’ve filed a bug assigned to myself (VSO#212461). If you’re using atomic on x86, you can work around this by applying alignas yourself.

*EDIT2

I also found that the problem is at D:\boost_1_60_0\boost\lockfree\detail\freelist.hpp on line 603

atomic<tagged_index> pool_;

Hope i helped.

Hello,

Its me again. So, for all of you that can't compile because of the version, here's my way to solve this:

1) Uninstall Visual Studio completely from your system using this: https://github.com/Microsoft/VisualStudioUninstaller/releases

2) Download the Community 2015.1 version of the Visual Studio from here: http://download.microsoft.com/download/5/7/A/57A99666-126E-42FA-8E70-862EDBADD215/vs2015.1.com_enu.iso

3) Be happy compiling again.

I know that's not the final solution but it's worked for me and maybe help someone while the official solution doesn't came from the developers both of the Forgotten and Boost C++.

Thank you.

@vinivst Or you could just go to your recent Windows updates and uninstall Update 2.

@jo3bingham For sure, but in my case i had not installed the 2015.1 version to get an update. So i already started from 2015.2 version. I think that probably there's some people like me out there.

The issues comes from the fact that we use boost::lockfree::stack and not the ThreadState enum. Boost.Lockfree is a header-only library, so upgrading to VS2015.2 should be sufficient.

Was this page helpful?
0 / 5 - 0 ratings