You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am working on converting the deal.II finite element library into something that can be built using C++20 modules. (See dealii/dealii#18071.) deal.II interfaces (along with many other libraries) with CGAL, and so one of the things that need to happen is that I need to wrap all of the functions and classes used from external dependencies of deal.II into modules to avoid the use of header files, since the latter do not play very well with C++20-style modules. This requires files that look like this and that "export" CGAL's declarations into a module: https://github.com/bangerth/dealii/blob/cxx-modules/cxx20-modules/interface_module_partitions/cgal.ccm
Like pretty much every other dependency, CGAL is providing an issue that turns out to be hard to work around. In CGAL's case it is that there are a bunch of named parameters that (through a process that -- how should I say that -- took a while to understand :-) ) are created via the following approach:
// In Named_function_parameters.h
#define CGAL_add_named_parameter_with_compatibility(X, Y, Z) \
const Boost_parameter_compatibility_wrapper<internal_np::X> Z;
// STL_Extension/internal/parameters_interface.h
CGAL_add_named_parameter_with_compatibility(facet_size_param_t, facet_size_param, facet_size)
The end result of this is that we get a const variable in the header file Named_function_parameters.h. const variables have "internal linkage", which means that they are in essence replicated in every translation unit (compiled .cc file) that includes this header file. For the current set of variables, that's not problematic since these variables are small, but it's nevertheless wasteful, for the same reasons as one shouldn't have static functions in header files.
For the module case, however, it's actually problematic because variables with internal linkage cannot be exported into a module.
The solution to this situation is the same as with function: Mark the variable as inline. That gives the variable external linkage, which means the linker will combine all occurrences of the same variable in multiple .o files into a single object in memory, in the same way it does for inline functions. It also makes the variable exportable for module purposes.
@lrineau No, constexpr implies const, but not inline. constexpr variables still have internal linkage unless you also mark them as inline.
Either way, the minimal change is in #8874, which works for me. Whether these variables should be constexpr is a separate question that I don't have enough insight into. If these variables are marked as constexpr, then they can be used in constexpr contexts, but that then also means that the member functions of the class type need to be constexpr. I don't know whether that's true, and so left it out of the patch. (My code compiles if I mark these variables as constexpr, but that doesn't mean anything: It compiles because I use these variables in non-constexpr contexts, but that doesn't mean that it would work if used in constexpr contexts. In fact, I cannot think of a good example where one would want to use these variables in constexpr contexts.)
@lrineau No, constexpr implies const, but not inline. constexpr variables still have internal linkage unless you also mark them as inline.
You are right. constexpr implies inlineonly for static data members. That is strange that it does not have the same implication for global variables. Thanks for your pull-request.
Activity
lrineau commentedon May 2, 2025
You are right. They should be
inline, and maybe evenconstexp.bangerth commentedon May 2, 2025
I have no opinion on
constexpr-- that's an orthogonal issue, as bothconstandconstexprboth make a variable have internal linkage.Would you like me to write a patch that adds the
inline?lrineau commentedon May 5, 2025
constexpractually impliesinline. That is why I suggested it.Yes, please submit a PR, once you have verified it does solve this issue. Thanks for your report. I wonder why our test suite has not caught it.
bangerth commentedon May 5, 2025
@lrineau No,
constexprimpliesconst, but notinline.constexprvariables still have internal linkage unless you also mark them asinline.Either way, the minimal change is in #8874, which works for me. Whether these variables should be
constexpris a separate question that I don't have enough insight into. If these variables are marked asconstexpr, then they can be used inconstexprcontexts, but that then also means that the member functions of the class type need to beconstexpr. I don't know whether that's true, and so left it out of the patch. (My code compiles if I mark these variables asconstexpr, but that doesn't mean anything: It compiles because I use these variables in non-constexprcontexts, but that doesn't mean that it would work if used inconstexprcontexts. In fact, I cannot think of a good example where one would want to use these variables inconstexprcontexts.)lrineau commentedon May 6, 2025
You are right.
constexprimpliesinlineonly for static data members. That is strange that it does not have the same implication for global variables. Thanks for your pull-request.Mark variables declared at global scope in headers as 'inline'. (#8874)
Mark variables declared at global scope in headers as 'inline'. (CGAL…