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.

Reply via email to