Skip to content

[C++20 modules] 'extern template' forward declaration of an instantiation does not work with modules. #153225

@bangerth

Description

@bangerth

Here's a rather obscure issue that works with header files but not with modules. Take the following code (complete set of files attached):

// a.ccm
module;
export module M;

// Declare and export a template class
export template <typename T> struct S {
  S();
};

// Say that S<int> is instantiated somewhere else
extern template struct S<int>;
// a.cc
module;
module M : impl;
import M;

// Implement the constructor
template <typename T>
S<T>::S() {}

// Do the instantiation of S<int> promised in a.ccm
template struct S<int>;
// b.cc
module;
export module b;
import M;

int main() {
  S<int> s;
}

The important part for this bug report is the extern template struct S<int>; declaration in a.ccm. It tells the compiler that some other translation unit provides an explicit instantiation of the template, which here we do in a.cc: template struct S<int>;. These sorts of declarations are optimizations in a header-based system: They tell compilers not to bother with implicit instantiations of certain templates because an explicit specialization is provided elsewhere. These optimizations are useful if, for example, the body of the template class had a bunch of long implementations of member functions.

Yet, something is going wrong with modules. When compiling these files, I get the following error message:

/usr/bin/ld: CMakeFiles/test.dir/b.cc.o: in function `main':
b.pcm:(.text+0xd): undefined reference to `S@M<int>::S()'

In other words, the existence of the extern template declaration in a.ccm resulted in the compiler not doing the explicit instantiation in a.cc at all, even though the code explicitly says to do so. This is clearly a bug. Removing the extern template line in a.ccm makes the linker error go away, but that's of course not the right solution :-)

Compiler version: 20.1.7. Complete test case: bug.tar.gz

@ChuanqiXu9 FYI

(This PR describes the issue referenced in dealii/dealii#18500. It is part of dealii/dealii#18071)

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:modulesC++20 modules and Clang Header Modules

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions