How to use standard library macros with std module in C++23
Asked Answered
A

1

7

I am currently playing with C++ modules, trying to modernize our company's code C++ base to use modules for the core features. In particular there is the upcoming C++23 std module which seems very interesting as a better alternative to precompiled headers.

So I am using Visual Studio 2022 17.5 Preview 2.0, which has a preliminary support for std module. By the way, I faced a compiler internal error, a bug that I reported to Microsoft.

In all our C++ source files, there is now an import std; statement, and this works quite well. Every identifier that is supposed to be in std namespace seem to be exported as expected. I measured a slight decrease of compilation time compared to the previous use of a precompiled header.

I found out that if you import std;, you have a lot of weird compilation errors in you also #include <> any standard C++ header, because Microsoft compiler get confused and complains about redefinition. So I took care of removing all of them.

My problem is that there are a few macros that are defined in standard library (mostly in C compatibility library), which are obviously not exported because C++ modules by design never export macros.

Our code base use a very limited number of those standard macros, but I think it would be hard to avoid them. Here is the short list of them (unsure it is complete):

  • stdout
  • errno
  • va_start, va_arg, va_end

For the va_* macros, I #include <stdarg.h> and it compiles fine on VS 2022, although it breaks the rule I previously mentioned. This is probably because this header has nearly only macros. But for stdout and errno, I don't know what to so.

Does C++23 specify how to access the important standard macros like stdout or errno when importing std module? Is there a good workaround?

Amphora answered 7/1, 2023 at 16:19 Comment(7)
For global identifiers from C, you might want to import std.compat.Rhu
@Ranoiaetep: That won't help for macros.Id
va_start, va_arg, and va_end can be wholly replaced by variadic templates and fold espressions; so there's one off the list.Blowzy
@Casey. No. Our code base actually declares type safe variadic templates, which then call a private C variadic function for actual implementation. I know this is a bit unusual, but proofed to be very powerful.Amphora
@Rhu Our code base is cross platform, although I am currently only playing on Visual Studio. The std.compat module is a Microsoft extension. And this does not export macros.Amphora
@prapin: "The std.compat module is a Microsoft extension." No, it's not.Id
@NicolBolas Thank you for the information, that could be helpful for me.Amphora
I
8

According to the C++ working draft:

A declaration in the standard library denotes the same entity regardless of whether it was made reachable through including a header, importing a header unit, or importing a C++ library module.

So this is probably a bug relative to C++23. Though considering that they only claim partial support for the C++23 modular standard library, it's not surprising.

However, for your specific problem, the issue is mostly solved. Many of these macros come from headers that only export the macros. errno comes from <cerrno>, and assert comes from <cassert>. stdout is a problem because it lives in <cstdio> which provides a lot more than just that macro.

Id answered 7/1, 2023 at 16:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.