Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.6k views
in Technique[技术] by (71.8m points)

c++20 - Two-Step Compile for C++ Modules?

Clang and GCC (and maybe MSVC?) are using a two-step compile for their modules implementation at the moment:

  • Generate the BMI/CMI (IPR for MSVC, if it still does this?) to be consumed by someone else's import.
  • Generate the object file to be feed to the linker.

It seems that there are some possible uses for modules that produce a BMI/CMI but that don't produce an object file, for example modules that only export types or constexpr variables used for conditional compilation.

As far as I can understand from the standard, there's nothing saying I have to produce/link the objects file. So I'm wondering if I've missed something obvious about using modules like this, and if we expect tooling to support this "build as a module, don't build as an object" workflow?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I expect modules to be able to provide definition for stuff that normally wouldn't be with headers.

Imagine this module:

export module hello;

export inline auto say_hello() -> char const* {
    return "hello world";
}

As you can see, the function is inline. It is also in the interface. Now with header, there is no place to put the implementation. For inline function to be possible, the language allow for multiple definition to be found. So each TU output their own definition in the object file.

That is repeated work that can be avoided using module. As you can see, module interface are TU just like any other cpp file. When you export an inline function, yes the implementation is available to other TU, but it won't be necessary for all tu to provide implementation, since it can be put in one place: the TU that has the inline function in it.

I expect the same thing with constexpr variables. They also need definition, since you may take a reference or an address to them. Take this for example:

export module foo;
import <tuple>;
export constexpr auto tup = std::tuple{1, 'a', 5.6f};
import foo;
int a = std::get<0>(tup);

The std::get function takes a reference to the tuple. Even though it's a constexpr variable, some context (especially without optimizations) may require the variable to be ODR used.

So in my example, even though the module foo only export a constexpr variable, I expect the cpp file to compile into an object file containing the definition.


It may also happen that there is nothing inside the object file. I also expect it to behave like an empty TU today:

// I'm empty

You can add such cpp file into a project without any problem, and link it to your executable. I expect the tools to behave the same with modules.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share

2.1m questions

2.1m answers

63 comments

56.5k users

...