Skip to content
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

Use PIMPL in our muParser implementation. #13577

Merged
merged 4 commits into from May 11, 2022

Conversation

drwells
Copy link
Member

@drwells drwells commented Mar 26, 2022

In #11609 we decided that we would not install the muParser headers. Our bundled version of muParser is a bit odd because its compiled directly into deal.II and the headers are not publicly available, but deal_II.so et al define all the standard muParser symbols: i.e., its a copy of muParser that conflicts with 'real' muParser installations but cannot be used as one. Hence, people unaware of how this works get weird crashes or link errors (like my student today).

This PR resolves that inconsistency by properly namespacing our own version: all the symbols now go in dealii::mu which will permit us to safely link against another copy of muParser. I also removed the need to have any muParser stuff in the headers at all by using the PIMPL tactic.

@drwells
Copy link
Member Author

drwells commented Mar 26, 2022

This is a very interesting clang-tidy complaint:

/jenkins/workspace/dealii-tidy_PR-13577/source/base/function_parser.cc:339:9: error: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast,-warnings-as-errors]

but: we do this all the time, see

Assert(dynamic_cast<const InternalData *>(&internal_data) != nullptr,
ExcInternalError());
const InternalData &data = static_cast<const InternalData &>(internal_data);

Perhaps the extra implicit conversion is getting in the way.

@drwells drwells force-pushed the muparser-pimpl branch 2 times, most recently from cbafe97 to d031294 Compare March 26, 2022 22:12
@drwells drwells mentioned this pull request Mar 26, 2022
@drwells
Copy link
Member Author

drwells commented Mar 26, 2022

adding NOLINT worked. I'm surprised the other places don't get caught by clang-tidy.

@drwells drwells force-pushed the muparser-pimpl branch 2 times, most recently from eb46097 to 7af6209 Compare March 27, 2022 01:29
@tjhei
Copy link
Member

tjhei commented Mar 27, 2022

I still think #11609 would have been great. You can also tell deal.II to use the external muparser and your case will work (but it is annoying, I know).

I am not sure about this workaround. Carrying patches on top of it makes it harder to update.

@drwells
Copy link
Member Author

drwells commented Mar 28, 2022

I don't like that in the future we will have to remember to do this but I think its still the right choice. We haven't updated muParser since 2015 - how about we update the bundled copy now and then apply this patch? That way we won't have to worry about this until 2029 or so.

Another option would be to define a preprocessor symbol indicating that we are using the bundled version and then check, with a test, that the correct symbols exist (e.g., dealii::mu::Parser).

@tjhei
Copy link
Member

tjhei commented Mar 28, 2022

how about we update the bundled copy now and then apply this patch

I think that makes sense.

Does your current PR work with an external muparser as well?

@drwells
Copy link
Member Author

drwells commented Mar 28, 2022

Can do! Yes, this works with an external muParser.

@tjhei
Copy link
Member

tjhei commented Mar 28, 2022

What do others think about this PR, @dealii/dealii ?

/**
* Destructor.
*/
virtual ~FunctionParser() override;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you no longer need this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can get rid of this since we are now using PIMPL: the default destructor, generated in the header, doesn't need to call ~mu::Parser() but instead calls ~internal::muParserBase() which is virtual (and overridden in the source file).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, never mind. It's because you now store a pointer to the base class which is visible in the header file.

@bangerth
Copy link
Member

I'm ok with wrapping header files.

@drwells
Copy link
Member Author

drwells commented Mar 28, 2022

This now relies on #13581 - lets not merge until that is in.

@drwells
Copy link
Member Author

drwells commented Apr 13, 2022

This can now be reviewed again since the other PR is in.

@peterrum peterrum added this to the Release 9.4 milestone Apr 24, 2022
Copy link
Member

@peterrum peterrum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but I am not an expert on muparser...

@drwells
Copy link
Member Author

drwells commented Apr 25, 2022

The windows link problem is really baffling. I'll take a closer look at this this week.

This should not have been ported to the new directory.
We should always set up the linkage options ourselves (i.e., always use
static linkage) and not let muParser try to set things up for dynamic
linkage in case we forget. This only applies to MSVC.
// Since this header is not installed this behavior change is purely internal.
#define API_EXPORT_CXX
#define MUPARSER_LOCAL
#define API_EXPORT(TYPE) TYPE
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how this worked on master, but we need to completely disable muParser's own MSVC DLL linkage fixes to get things to work consistently.

@drwells
Copy link
Member Author

drwells commented May 10, 2022

Would someone take another look?

@luca-heltai
Copy link
Member

I'm ok with this. If no one objects, I'd go ahead and merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants