Providing default constructors for structs breaks use of designated initializers
Closed this issue · 5 comments
Using Sundials in a C++20 program results in no clean way to instantiate custom SUNLinearSolvers (and other obejcts).
The usual
struct _generic_SUNLinearSolver_Ops LSOps =·
{
.gettype = SunLinSolWrapper::LSGetType,
.getid = SunLinSolWrapper::LSGetID,
.setatimes = nullptr, ...
};
Isn't permitted because the default constructor makes _generic_SUNLinearSolver_Ops a non-aggregate type.
From include/sundials/sundials_linearsolver.h:127
#ifdef __cplusplus
_generic_SUNLinearSolver_Ops() = default;
#endif
Removing this default constructor results in a pure aggregate type and declaring the default constructor should not be necessary.
I know this is low priority, but flagging this as usage of C++20 will only increase.
For reference, this issue occurs with C++20 because C++20 changed the definition of an aggregate so that it cannot have any constructor, while previously a default constructor was acceptable.
Right, I guess the question is -- was the default constructor needed for something specific.
By my reading the C++ standard defines the behaviour of constructing an aggregate to be exactly what the default constructor would have done (in this case, with simple types). So it should be fine to just remove, but if there's a particular reason it was there I'm happy to debug whether removing it is an issue.
I cannot recall exactly why the default constructor was added. Removing it does not seem to break anything in my limited testing so far. If you are able to try it out as well, that would be great. Here is the branch where I removed it https://github.com/LLNL/sundials/tree/bugfix/cpp20-aggregate.