-
Notifications
You must be signed in to change notification settings - Fork 967
Add possible workaround to compiler-error-c2603.md #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Added information about a possible workaround for compiler error c2603. This workaround was tested in Visual Studio 2013.
@KorkyPlunger, It will cover your contributions to all Microsoft-managed open source projects. |
The workaround does not appear to work, at least in the last couple of compiler versions.
The C2603 error does not occur in recent compilers where thread safe init is the default, hence the /Zc:threadSafeInit- switch to trigger it. |
Interesting. We're using VS2013, and I tested this both in our production code and in a small test app. If you just create a basic Win32 console app using the project wizard in VS2013 and paste in the workaround code, that compiles cleanly for me (and fails with the error if you remove the lambda). I tested this in VS2015 via http://webcompiler.cloudapp.net/ and you are correct: if I pass the /Zc:threadSafeInit- flag then it does not compile with the lambda. So it seems this workaround may be specific to VS 2013 (and possibly 2012?) |
I've updated the PR to include information about version-specific differences. |
I've run the lambda idea past the compiler team, and they do not like it for several reasons. One is that it probably works because in the 2013 compiler, this particular lambda breaks the inline/comdat request, so you are silently paying for a function call to f1 when you expect inline behavior. A code clarity issue arises because the statics in the lambda are only visible within the lambda, so you wind up with an oddly doubly-wrapped function body if you want to make use of them. And finally, this technique is not forward compatible with updated compilers that are better at inlining the lambda. When you update your toolset, this would once again expose the issue if you've turned on the backward compatibility flag. You'd wind up with a regression on an issue you thought you'd fixed. If you're willing to pay the performance penalty of not having the function be comdat/inline, then you'd be better off making it explicit with a forwarding function, like so:
One developer suggested that if the statics are all of the same type as in the example, as a work around, you could allocate an array as a single static entry, and use references to individual elements of the array. This has the dual advantage of both maintaining the inline/comdat performance, and of being something you wouldn't need to go back and fix up when you moved to a newer toolset. Moving to a newer toolset that implements magic statics is really the best solution anyway; you can now define as many statics as you like without a krufty work around. Mentions of the /Zc:threadSafeInit flag are a useful addition to this topic. I'll work on incorporating that information here. |
Thanks to your input, I've poked some discussion of possible resolutions and a link to the /Zc:threadSafeInit topic into C2603. I appreciate your proposal and the time you took to work on it, even if it didn't go in exactly as you wrote it. |
No problem, I was just hoping to save other developers time (and I hadn't checked the latest compilers before writing the proposal). I agree that magic statics are the way to go. Glad we've got more information in the docs now. |
Added information about a possible workaround for compiler error c2603. This workaround was tested in Visual Studio 2013.