https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127642
Bug ID: 127642
Summary: [modules] Conflicting type for imported declaration
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: d7d1cd at mail dot ru
Target Milestone: ---
So, let's take a header with the following content:
$ cat header.h
#include <chrono>
#include <print>
inline void foo(std::chrono::seconds s) {
std::println("{}", s);
}
We include this header in the module's global module fragment:
$ cat module.ixx
module;
#include "header.h"
export module M;
void bar(std::chrono::seconds s) {
foo(s);
}
Next, we create a translation unit (TU) where we include both our header and
our module:
$ cat main.cc
#include "header.h"
import M;
int main() {}
We try to build it and get a compilation error:
$ g++ -std=c++26 -fmodules module.ixx main.cc
In file included from /usr/local/gcc-trunk/include/c++/16/chrono:3695,
from header.h:1,
from module.ixx:2,
of module M, imported at main.cc:2:
/usr/local/gcc-trunk/include/c++/16/bits/chrono_io.h:903:38: error:
conflicting type for imported declaration ‘constexpr const char* const
std::__format::__formatter_chrono<char>::_S_months [12]’
903 | static constexpr const _CharT* _S_months[]
| ^~~~~~~~~
In file included from /usr/local/gcc-trunk/include/c++/16/chrono:3695,
from header.h:1,
from main.cc:1:
/usr/local/gcc-trunk/include/c++/16/bits/chrono_io.h:903:38: note: existing
declaration ‘constexpr const char* const
std::__format::__formatter_chrono<char>::_S_months []’
903 | static constexpr const _CharT* _S_months[]
| ^~~~~~~~~
/usr/local/gcc-trunk/include/c++/16/bits/chrono_io.h:892:38: error:
conflicting type for imported declaration ‘constexpr const char* const
std::__format::__formatter_chrono<char>::_S_weekdays [7]’
892 | static constexpr const _CharT* _S_weekdays[]
| ^~~~~~~~~~~
/usr/local/gcc-trunk/include/c++/16/bits/chrono_io.h:892:38: note: existing
declaration ‘constexpr const char* const
std::__format::__formatter_chrono<char>::_S_weekdays []’
892 | static constexpr const _CharT* _S_weekdays[]
| ^~~~~~~~~~~
In file included from /usr/local/gcc-trunk/include/c++/16/chrono:51:
/usr/local/gcc-trunk/include/c++/16/bits/chrono.h:1380:66: note: during
load of pendings for ‘std::chrono::duration’
1380 | { return chrono::duration<long double, ratio<3600,1>>{__hours};
}
| ^
Here is a reproduction of this example in an online compiler:
https://godbolt.org/z/bEaKao4zE
The error reproduces in C++26 and in compiler versions trunk, 16.2, and 16.1.
It does not reproduce in versions 15.x. Furthermore, the error does not occur
with the C++23 standard version on any compiler.
One more thing: shouldn't constant definitions in headers be marked `inline`?
As it stands, the `_S_months` array (and others) ends up in every translation
unit, resulting in multiple copies within the executable file. Ultimately,
there should be just a single symbol shared by all of them.