Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is mixing modules and headers in C++20 possible / acceptable?

I'm actually trying to understand the C++20 modules system by writing my own little module. Let's say I want to provide a function that deletes all the spaces at the beginning and the end of a string (a trim function). The following code works without problem.

module;

export module String;

import std.core;

export std::string delete_all_spaces(std::string const & string)
{
    std::string copy { string };

    auto first_non_space { std::find_if_not(std::begin(copy), std::end(copy), isspace) };
    copy.erase(std::begin(copy), first_non_space);

    std::reverse(std::begin(copy), std::end(copy));
    first_non_space = std::find_if_not(std::begin(copy), std::end(copy), isspace);
    copy.erase(std::begin(copy), first_non_space);
    std::reverse(std::begin(copy), std::end(copy));

    return copy;
}
import std.core;
import String;

int main()
{
    std::cout << delete_all_spaces("  Hello World!    \n");
    return 0;
}

But what if I want to use only specific headers instead of std.core in my module? If I do so, replacing the import std.core by the following code, I get an error on Visual Studio 2019.

module;

#include <algorithm>
#include <cctype>
#include <string>

export module String;

// No more import of std.core

export std::string delete_all_spaces(std::string const & string)
{
    // ...
}
Error LNK1179 file not valid or damaged: '??$_Deallocate@$07$0A@@std@@YAXPAXI@Z' COMDAT duplicated

However, if in the main.cpp I remplace as well the import std.core with #include <iostream>, the code compiles again. It's like using both system provents the linker to do its job.

The question is: am I doing it wrong? Is it a bad practice to use both the new import and the old #include methods? I saw on multiple posts on the Internet that you can include some old headers in your module, thus modernizing your code without breaking the existing. But what if this header includes some part of the STL, like #include <string> but my module uses import std.core?

I'm testing only with Visual Studio 2019 because, as of now, import std.core does not work with GCC. So, may it comes from a bug in VS? Or will the problem be the same for all compilers?

like image 595
informaticienzero Avatar asked Jan 27 '21 11:01

informaticienzero


People also ask

Why are modules better than headers?

Modules eliminate or reduce many of the problems associated with the use of header files. They often reduce compilation times. Macros, preprocessor directives, and non-exported names declared in a module aren't visible outside the module.

What is a module header?

A module header specifies linkage information that the compiler or executor uses to resolve names mentioned within the module body. Unlike the bulk of an Avail program, which uses an extremely fluid syntax, a module header has a rigid structure that revolves around a small vocabulary of fixed keywords.

How to create a module in Cpp?

Add a module unit implementation file by creating a source file with a right-click in the Solution Explorer on Source Files, select Add > New item and then select C++ File (. cpp). Give the new file the name BasicPlane.

What are modules in c++20?

Modules are the new C++20 method for importing functions and classes from external libraries and separate translational units. Modules provide an alternative to using header files. Some of the benefits of modules are: No need to write separate files for the interface ( .h) and the implementation ( .cpp)

What is precompiled headers in c++20?

Precompiled headers can be a very effective way of speeding up compile times. Also, removing implementation details from the interface file (e.g. using the PIMPL idiom) reduces the ‘ripple effect’ and prevents unnecessary recompilation when small changes are introduced. Defining and using modules in C++20 requires the use of the following tokens:

What is the difference between import and export in c++20?

Technically, export is an existing C++ keyword which takes on a new significance in C++20, whereas import and private become identifiers with special meaning. A module is a way of packaging code (e.g. a library or API) for reuse. A module is referenced by name rather than by the header file it lives in, e.g.:

Which headers are importable in C++?

Which headers are importable is implementation-defined, but the C++ standard guarantees that all standard library headers are importable headers. The ability to import excludes C headers. What's Next? In my next post, I use variadic templates to implement the C++ idiom for a fully generic factory.


1 Answers

Yes, modules can be used together with header files. we can both import and include headers in the same file, this is an example:

import <iostream>
#include <vector>
int main()
{
  std::vector<int> v{1,6,8,7};
  for (auto i:v)
    std::cout<<i;
  return 0;
}

When you create modules, you're free to export entities in the interface file of the module and move the implementations to other files. to conclude, the logic is the same as in managing .h and .cpp files

like image 110
ic_QCOMEngineer Avatar answered Oct 19 '22 23:10

ic_QCOMEngineer