17

after update VS2015.1 next code no longer compiles:

class testClass
{
static const std::vector<int> test;
};

initialization

const std::vector<int> testClass::test =
{
    1,2
};

with error:

error C4592: 'test': symbol will be dynamically initialized (implementation limitation)

is it bug or something has changed in the compiler?

7
  • 1
    Compiled fine for me. You're using Visual Studio 2015 Community? Commented Dec 1, 2015 at 7:11
  • yes 2015 Community, just checked on empty project, its compiled fine too Commented Dec 1, 2015 at 7:15
  • Maybe it's something else, could you show some more code to provide a better context? Commented Dec 1, 2015 at 7:17
  • Its big UE4 project, but problem that it was compiled fine before VS update, and error is very strange, I suppose for me will be better to remove update Commented Dec 1, 2015 at 7:27
  • 2
    I believe what the warning is saying is that the value won't be set at compile-time, but at run-time, since it is set through an initializer list. It's a weird case to be sure. Commented Dec 1, 2015 at 8:18

4 Answers 4

39

VC++ compiler dev here.

Peter Ruderman's answer is almost correct. The warning was really meant for constexpr objects where a constexpr constructor call is involved in the initialization. In Update1, we can now statically initialize literal types and some non-literal types with constexpr constructors but not all. Specifically, having virtual member functions will prevent static initialization even though the type has a constexpr constructor and is supplied with a constant initializer. The warning was meant to diagnose such cases. Unfortunately, there was a bug that caused it to fire when the types of the expressions in the initializer list had constexpr constructors (in the OP's example std::vector doesn't, but std::initializer_list does). This warning can be safely ignored since the compiler is not doing anything different from before.

We've fixed the bug but unfortunately it was found too late to include in Update 1. In any case, the need for this warning should go away when we do a more complete implementation of constant initialization (3.6.2).

Tanveer Gani Visual C++ Team.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the reply, Tanveer. Will the constant initialization implementation be completed in update 2? Also, I'm getting this warning for a class with no virtual methods at all. Are there other known issues that prevent static initialization?
Can we get this documented on MSDN? It's quite frustrating to get warnings that aren't listed anywhere on MSDN, especially when their cause is subtle like this.
According to Tanveer the bugfix is supposed to be included post Update 1. However, I still have this issue with Update 3.
9

Unfortunately, I don't have enough "reputation" to comment, so I'll add my comments here.

@Peter Ruderman: complete support for constant initialization is on the list. I can't say yet whether it'll make it into Update 2 but we'll do our best. You're getting a warning for a type without constexpr constructors because of the bug which detected a different constexpr constructor in the call-tree. This usually comes from std::initializer_list<>.

@Peter Ruderman: Also, a slight correction: for static lifetime objects initialized with a constexpr constructor call, static initialization is required only if the initializer is a constant-initializer, i.e., consists only of constant expressions. Update1 does this for but not for types containing virtual functions.

Also: in the OP's code, no static initialization is required, though I suppose a compiler can do it for quality-of-implementation reasons. This is because 'const' was used rather than 'constexpr', the latter requiring static initialization.

To reiterate: disabling this warning is perfectly reasonable (and safe).

Comments

4

in my case I solved this by usage of std::array, and it works for me, but in general case, I suppose that warning disabling is solution

#pragma warning( disable : 4592)

2 Comments

@MarkoPopovic well pragma disables warning in single file but if warning doesn't make much sense, disabling it is the only option I guess.
I'm having the same issue, and I simply added a #pragma warning( push ) #pragma warning( disable : 4592) before my initilization, then a #pragma warning( pop ) right after
1

I believe that the warning is triggered by new logic for detecting when the compiler generates dynamic initializers for static objects with constexpr constructors. It doesn't make sense to raise it in this particular case because std::vector has no constexpr constructors. So that's bug number 1.

Bug number 2 is that static objects with constexpr constructors still get dynamic initializers. This was supposed to be fixed in update 1 but apparently Microsoft was unable to do it.

When you initialize a type with a constexpr constructor at module level, the compiler should be able to run the constructor itself and embed the fully constructed object directly in your image file. This doesn't currently work in VC, however. Instead it will create a dynamic initializer and initialize the object at runtime when your program first starts.

The warning is trying to make this problem visible. It's safe to ignore in most cases, and it's certainly safe to ignore in this specific case.

5 Comments

constexpr constructor on std::vector?
I believe this is happening because of the way Microsoft has it implemented. Digging (just a little) into the implementation, I see that they do have constexpr on _Compressed_pair which is a base of vector. It could be that the compiler is being too liberal in choosing when to issue the warning. Hopefully both problems will go away in the next update.
Well I'm not sure if that's really possible for the vector to construct it in compile-time, at least you'll have to check in destructor which type of construction was performed somehow. However this warning is also issued for non-const global vector, to which you can as well do push_back, I wonder how initialization of this one could be done statically.
@PeterRuderman Yeah, that was my point, that it's unlikely for this particular case to indicate a problem with the implementation of static initialization in MSVC, but rather with the criteria for issuing that warning - basically, it's entirely spurious in this case. I think it's worth clarifying this in the answer.
Agreed. I've edited my answer, but it seems we have a better one now anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.