-
Notifications
You must be signed in to change notification settings - Fork 284
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
Fix MS VC 2019 build #3137
Fix MS VC 2019 build #3137
Conversation
@@ -190,25 +194,6 @@ void FEMContext::use_unweighted_quadrature_rules(int extra_quadrature_order) | |||
|
|||
void FEMContext::init_internal_data(const System & sys) | |||
{ | |||
// Reserve space for the FEAbstract and QBase objects for each |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't delete this code because it's a workaround for another compiler (Intel). In addition this potentially changes the behavior of the code because init_internal_data()
could theoretically be called multiple times (not sure if it actually is) and we would need _element_fe
, _side_fe
, etc. to be cleared each time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
How can I test ICC build (e.g on Linux)?
-
Currently init_internal_data() is private and is only called from the constructor.
-
The problem with MS VC 2019 is that neither of this works:
std::vector<std::map<int, std::unique_ptr<const char *>>> v1;
v1.resize(1); // error: attempting to reference a deleted function
v1.push_back(std::map<int, std::unique_ptr<const char *>>()); // DITTO
v1.push_back(std::move(std::map<int, std::unique_ptr<const char *>>())); // DITTO
v1.emplace_back(std::map<int, std::unique_ptr<const char *>>()); // DITTO
v1.emplace_back(std::move(std::map<int, std::unique_ptr<const char *>>())); // DITTO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe try emplace_back()
?
How can I test ICC build (e.g on Linux)?
We no longer have CI testing of the Intel compiler, unfortunately. If you can find some other workaround that fixes MSVC then we could consider ifdef
'ing based on the compiler. Honestly I find it surprising that two different compilers have issues with the same (otherwise innocuous looking) lines of code. I'm pretty sure the code is standards conforming and it's the compilers that are wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the problem is not in the compilers but in their STL implementations.
The problem with this piece of code is that std::unique_ptr<> is non-copyable (it has copy constructor explicitly deleted), but std::vector::push_back() may involve copying.
The same about std::vector::resize() which may re-allocate memory and copy objects from old location to new.
resize() and push_back() implementations can use move constructors, but likely ICC 19 and MS VC 2019 got it wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jwpeterson yes, I also tried emplace_back() - produces the same error with MS VC 2019
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I submitted a less intrusive change, but I don't think that different codepaths and #ifdef-fu is a good thing.
I am almost sure construction of vector of specified size will work in older ICC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am almost sure construction of vector of specified size will work in older ICC
Yes, it's possible you are correct. Looking back to the original change (7e6abb4) the only offending lines were the resize()
calls, no compiler that I'm aware of has complained about the constructor initialization syntax. This raises the question of whether MSVC/ICC19 would accept the syntax
_element_fe = std::vector<std::map<FEType, std::unique_ptr<FEAbstract>>>(4);
for reinitializing the vector with four empty maps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jwpeterson bingo! I tested the fix and updated the PR
eaea0de
to
65de730
Compare
Rather than clearing the vector of maps and then restoring empty maps, would it work to loop over the maps and clear them individually? |
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\xmemory(714): error C2280: 'std::pair<const libMesh::FEType,std::unique_ptr<libMesh::FEAbstract,std::default_delete<libMesh::FEAbstract>>>::pair(const std::pair<const libMesh::FEType,std::unique_ptr<libMesh::FEAbstract,std::default_delete<libMesh::FEAbstract>>> &)': attempting to reference a deleted function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Latest diff looks good to me. I will just throw in a comment that these two lines are a resize()
workaround for the Intel 19 and MSVC STL implementations before merging (once the CI all passes again).
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\xmemory(714): error C2280: 'std::pair<const libMesh::FEType,std::unique_ptr<libMesh::FEAbstract,std::default_deletelibMesh::FEAbstract>>::pair(const std::pair<const libMesh::FEType,std::unique_ptr<libMesh::FEAbstract,std::default_deletelibMesh::FEAbstract>> &)': attempting to reference a deleted function