如何在 C++23 中将标准库宏与 std 模块一起使用

pra*_*pin 7 c++ c++-modules c++23

我目前正在使用 C++ 模块,尝试对我们公司的代码 C++ 基础进行现代化改造,以使用模块来实现核心功能。特别是即将推出的 C++23std模块,作为预编译头的更好替代品,它看起来非常有趣。

所以我使用的是Visual Studio 2022 17.5 Preview 2.0,它对模块有初步支持std。顺便说一句,我遇到了编译器内部错误,我向Microsoft报告了这个错误。

在我们所有的 C++ 源文件中,现在都有一个import std;语句,而且效果很好。每个应该位于std命名空间中的标识符似乎都按预期导出。我测量到与之前使用预编译头相比,编译时间略有减少。

我发现,如果你,你在任何标准import std;C++ 头文件中都会遇到很多奇怪的编译错误,因为 Microsoft 编译器会感到困惑并抱怨重新定义。所以我小心翼翼地将它们全部删除。 #include <>

我的问题是,标准库中定义了一些(主要是在 C 兼容库中),这些宏显然没有导出,因为 C++ 模块在设计上从不导出宏

我们的代码库使用的标准宏数量非常有限,但我认为很难避免它们。以下是它们的简短列表(不确定是否完整):

  • stdout
  • errno
  • va_start, va_arg,va_end

对于va_*宏,我#include <stdarg.h>和它在 VS 2022 上编译得很好,尽管它打破了我之前提到的规则。这可能是因为该标头几乎只有宏。但对于stdouterrno,我不知道该怎么办。

C++23 是否指定在导入模块时如何访问重要的标准宏,例如stdout或?有没有好的解决方法?errnostd

Nic*_*las 8

根据C++ 工作草案

标准库中的声明表示同一实体,无论它是通过包含标头、导入标头单元还是导入 C++ 库模块使其可访问。

所以这可能是相对于 C++23 的一个错误。尽管考虑到他们只声称部分支持 C++23 模块化标准库,但这并不奇怪。

但是,对于您的具体问题,问题已基本解决。其中许多宏来自导出宏的标头。errno来自于<cerrno>,又assert来自于<cassert>stdout是一个问题,因为它所<cstdio>提供的不仅仅是那个宏。