Skip to content

Let global variables have external linkage. #8871

Closed

Description

@bangerth

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.

Would you accept a patch to that end?

Activity

  1. lrineau commented on May 2, 2025

    @lrineau
    Member

    You are right. They should be inline, and maybe even constexp.

  2. bangerth commented on May 2, 2025

    @bangerth
    ContributorAuthor

    I have no opinion on constexpr -- that's an orthogonal issue, as both const and constexpr both make a variable have internal linkage.

    Would you like me to write a patch that adds the inline?

  3. lrineau commented on May 5, 2025

    @lrineau
    Member

    constexpr actually implies inline. 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.

  4. bangerth commented on May 5, 2025

    @bangerth
    ContributorAuthor

    @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.)

  5. added this to the 6.1-beta milestone on May 5, 2025
  6. lrineau commented on May 6, 2025

    @lrineau
    Member

    @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 inline only for static data members. That is strange that it does not have the same implication for global variables. Thanks for your pull-request.

  7. added a commit that references this issue on May 16, 2025
    8978dde
  8. added a commit that references this issue on Jan 14, 2026
    9bf4993
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions