|
Boost : |
From: Ruben Perez (rubenperez038_at_[hidden])
Date: 2025-01-12 20:51:26
Hi all,
I finally have something workable regarding Boost and C++20 modules.
I've described it in detail in this article [1], but here's a rough
summary:
I've modularized Boost.Mp11 [2] (as an example of a header-only
library) and Boost.Charconv [3] (as an example of a compiled library).
I know that Charconv is not very useful in C++20, but it has few
dependencies and is relatively simple. I've also changed all tests in
these libraries to consume them as C++20 modules in modular builds,
and added CI jobs.
In the process, I've found a couple of what I think are MSVC bugs:
* An excess in pruning template specializations declared in the GMF,
even when they are (I think) decl-reachable from the purview [4].
* A problem when an exported using declaration targets another using
declaration declared in the GMF [5].
(I've reported the bugs this past weekend, so they might be pending
Microsoft's approval when you read this. I've pasted the bug report
descriptions at the bottom of the email, just in case).
Could any module expert confirm that these are indeed bugs?
Other than that, I'd like to get some feedback on this, and whether
you think this proposal is worth the effort.
Many thanks,
Ruben.
[1] https://anarthal.github.io/cppblog/modules3
[2] https://github.com/boostorg/mp11/pull/104
[3] https://github.com/boostorg/charconv/pull/255
[4] https://developercommunity.visualstudio.com/t/C20-modules:-specialzations-in-the-glo/10826499
Declarations in the global module fragment should not be discarded if
they are decl-reachable from an exported entity within the module
(http://eel.is/c++draft/module.global.frag). MSVC doesn't seem to
apply this rule to template specializations.
Minimal reproduction follows. Project layout:
/mylib/include/third_party.hpp
/mylib/include/mylib.hpp
/mylib/modules/mylib.cppm
/main.cpp
Contents of /mylib/include/third_party.hpp:
namespace third_party {
template <class T>
struct is_error_code_enum { inline static constexpr bool value = false; };
}
Contents of /mylib/include/mylib.hpp:
#include <third_party.hpp>
namespace mylib {
enum class myenum { v = 1 };
}
template<>
struct third_party::is_error_code_enum<mylib::myenum> { inline static
constexpr bool value = true; };
Contents of /mylib/modules/mylib.cppm:
module;
#include <mylib.hpp>
export module mylib;
export namespace mylib {
using mylib::myenum;
void f(third_party::is_error_code_enum<mylib::myenum>) {} //
specialization is decl-rechable
}
Contents of /main.cpp:
#include <mylib/include/third_party.hpp>
import mylib;
int main(){
static_assert(third_party::is_error_code_enum<mylib::myenum::value>); // fails
}
[5] https://developercommunity.visualstudio.com/t/MSVC-C20-modules:-export-using-templat/10826448
When a template alias is defined in the global module fragment, then
exported with the export using technique, and finally imported in a
source file, the compiler fails to parse the importing source file.
Project setup:
/mylib/include/mylib.hpp
/mylib/modules/mylib.cppm
/main.cpp
Contents of /mylib/include/mylib.hpp:
namespace mylib {
template<typename T, T N>
struct some_constant {};
template int N
using mp_size_t = some_constant<int, N>;
}
Contents of /mylib/modules/mylib.cppm
module;
#include <mylib.hpp>
export module mylib;
export namespace mylib {
using mylib::mp_size_t;
}
Contents of /main.cpp:
import mylib;
int main(){
mylib::mp_size_t<0> var;
}
Compiler error:
[redacted]\main.cpp(4): error C2059: syntax error: '<'
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk