https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115946
Bug ID: 115946 Summary: lambda in class body should have the same type among different TUs Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: namniav at gmail dot com Target Milestone: --- [basic.def.odr#15.6](https://eel.is/c++draft/basic.def.odr#15.6) > In each such definition, except within the default arguments and default > template arguments of `D`, corresponding *lambda-expression*s shall have > the same closure type When the lambda expression is used inside class body(but not inside a function), GCC generates different closure types in different TUs. Clang with libc++ has a similar problem only when the lambda is used in `decltype`(reported: https://github.com/llvm/llvm-project/issues/98963). Clang with libstdc++ seems not have this problem. Demo: https://godbolt.org/z/M4xjWesYn * common.hpp ```c++ #include <typeinfo> #include <array> struct A { using F1 = decltype([]{}); // GCC generates different closure types for different TUs inline static auto f2 = []{}; using F2 = decltype(f2); // GCC generates different closure types for different TUs }; [[gnu::always_inline]] inline auto func() { using F3 = decltype([]{}); // OK auto f4 = []{}; using F4 = decltype(f4); // OK return std::array{ &typeid(F3), &typeid(F4) }; } auto FOOBAR() { auto t = func(); return std::array{ &typeid(A::F1), &typeid(A::F2), t[0], t[1] }; } ``` * foo.cpp ```c++ #define FOOBAR foo #include "common.hpp" ``` * bar.cpp ```c++ #define FOOBAR bar #include "common.hpp" ``` * main.cpp ```c++ #include <cstdio> #include <typeinfo> #include <array> std::array<const std::type_info*, 4> foo(); std::array<const std::type_info*, 4> bar(); int main() { auto f = foo(); auto b = bar(); for (int i = 0; i < 4; ++i) { std::printf("F%d same type ? %d\n", i+1, *f[i] == *b[i]); //std::printf("name=%s hash_code=%-20llu addr=%p\n", f[i]->name(), (unsigned long long)f[i]->hash_code(), f[i]); //std::printf("name=%s hash_code=%-20llu addr=%p\n", b[i]->name(), (unsigned long long)b[i]->hash_code(), b[i]); } } ``` **Outputs** : * Clang, libc++ > ``` > F1 same type ? 0 > F2 same type ? 1 > F3 same type ? 1 > F4 same type ? 1 > ``` * Clang, libstdc++ > ``` > F1 same type ? 1 > F2 same type ? 1 > F3 same type ? 1 > F4 same type ? 1 > ``` * GCC, libstdc++ > ``` > F1 same type ? 0 > F2 same type ? 0 > F3 same type ? 1 > F4 same type ? 1 > ```