59

There are already two compilers that support C++ modules:

When starting a new project now, what should I pay attention to in order to be able to adopt the modules feature when it is eventually released in my compiler?

Is it possible to use modules and still maintain compatibility with older compilers that do not support it?

Smi
  • 13,850
  • 9
  • 56
  • 64
user7610
  • 25,267
  • 15
  • 124
  • 150
  • 3
    I am a little bit cowed to give an answer to a person with more than 2400 reputationpoints... ^^ I ask myself is it realy important to write every time when a new upgrade of c++ is released to change all my code to the new features? That would cause a lot of side-effects or architecual changes... If I were you I would write my own meta-language that would be constant (or where I have more control about) and I would write a function to transfer my language in to any other native programming language of my choise. This is like the idea of a virtualization of hardware. –  Jan 07 '16 at 10:15
  • 2
    @NECIPS SO is a knowledge base, you are not answering to me, but "to the world". If somebody asked me this question in person, I would say "Go write a test project, play with it and figure it out for yourself". Few years ago, somebody would do just that and write a blog post about it. Now I am hoping somebody will write a SO answer. – user7610 Jan 07 '16 at 11:43
  • Maybe "Waldo" can answer your question (http://theres-waldo.ca/2014/07/17/trip-report-c-standards-committee-meeting-in-rapperswil-june-2014/) –  Jan 07 '16 at 13:19
  • 1
    This is a packaging problem. At the end, a module is just a view on ressource. You can use the "code resource" as source, bin+.h or module. If you are familiar with packaging systems (CoApp for microsft VSxxx for instance) you should not care too much of this. Anyway the kiey is always your hability to separate the concepts of your system ... – norisknofun Feb 09 '16 at 14:55
  • Using modules means importing them with the `import` directive. Older compilers do not know the import directive. Therefore it is not possible to use modules and remain backwards compatible. Some preprocessor trickery may offer a way out, but IMO it is not worth it. – user7610 Feb 11 '16 at 10:24
  • "We still have hopes for Modules in C++20, but even getting them in C++23 will be a huge win for the whole C++ community." http://go.jetbrains.com/n0QR0eT01rQO0DV00Q10MRQ – user7610 Dec 21 '18 at 16:44

2 Answers2

30

There are already two compilers that support C++ modules

clang: http://clang.llvm.org/docs/Modules.html MS VS 2015: http://blogs.msdn.com/b/vcblog/archive/2015/12/03/c-modules-in-vs-2015-update-1.aspx

The Microsoft approach appears to be the one gaining the most traction, mainly because Microsoft are throwing a lot more resources at their implementation than any of the clang folk currently. See https://llvm.org/bugs/buglist.cgi?list_id=100798&query_format=advanced&component=Modules&product=clang for what I mean, there are some big showstopper bugs in Modules for C++, whereas Modules for C or especially Objective C look much more usable in real world code. Visual Studio's biggest and most important customer, Microsoft, is pushing hard for Modules because it solves a whole ton of internal build scalability problems, and Microsoft's internal code is some of the hardest C++ to compile anywhere in existence so you can't throw any compiler other than MSVC at it (e.g. good luck getting clang or GCC to compile 40k line functions). Therefore the clang build tricks used by Google etc aren't available to Microsoft, and they have a huge pressing need to get it fixed sooner rather than later.

This isn't to say there aren't some serious design flaws with the Microsoft proposal when applied in practice to large real world code bases. However Gaby is of the view you should refactor your code for Modules, and whilst I disagree, I can see where he is coming from.

When starting a new project now, what should I pay attention to in order to be able to adopt the modules feature when it is eventually released in my compiler?

In so far as Microsoft's compiler is currently expected to implement Modules, you ought to make sure your library is usable in all of these forms:

  1. Dynamic library
  2. Static library
  3. Header only library

Something very surprising to many people is that C++ Modules as currently expected to be implemented keeps those distinctions, so now you get a C++ Module variant for all three of the above, with the first most looking like what people expect a C++ Module to be, and the last looking most like a more useful precompiled header. The reason you ought to support those variants is because you can reuse most of the same preprocessor machinery to also support C++ Modules with very little extra work.

A later Visual Studio will allow linking of the module definition file (the .ifc file) as a resource into DLLs. This will finally eliminate the need for the .lib and .dll distinction on MSVC, you just supply a single DLL to the compiler and it all "just works" on module import, no headers or anything else needed. This of course smells a bit like COM, but without most of the benefits of COM.

Is it possible to use modules in a single codebase and still maintain compatibility with older compilers that do not support it?

I'm going to assume you meant the bold text inserted above.

The answer is generally yes with even more preprocessor macro fun. #include <someheader> can turn into an import someheader within the header because the preprocessor still works as usual. You can therefore mark up individual library headers with C++ Modules support along something like these lines:

// someheader.hpp

#if MODULES_ENABLED
#  ifndef EXPORTING_MODULE
import someheader;  // Bring in the precompiled module from the database
// Do NOT set NEED_DEFINE so this include exits out doing nothing more
#  else
// We are at the generating the module stage, so mark up the namespace for export
#    define SOMEHEADER_DECL export
#    define NEED_DEFINE
#  endif
#else
// Modules are not turned on, so declare everything inline as per the old way
#  define SOMEHEADER_DECL
#  define NEED_DEFINE
#endif

#ifdef NEED_DEFINE
SOMEHEADER_DECL namespace someheader
{
  // usual classes and decls here
}
#endif

Now in your main.cpp or whatever, you simply do:

#include "someheader.hpp"

... and if the compiler had /experimental:modules /DMODULES_ENABLED then your application automagically uses the C++ Modules edition of your library. If it doesn't, you get inline inclusion as we've always done.

I reckon these are the minimum possible set of changes to your source code to make your code Modules-ready now. You will note I have said nothing about build systems, this is because I am still debugging the cmake tooling I've written to get all this stuff to "just work" seamlessly and I expect to be debugging it for some months yet. Expect to see it maybe at a C++ conference next year or the year after :)

Niall Douglas
  • 9,212
  • 2
  • 44
  • 54
5

Is it possible to use modules and still maintain compatibility with older compilers that do not support it?

No, it is not possible. It might be possible using some #ifdef magic like this:

#ifdef CXX17_MODULES
    ...
#else
    #pragma once, #include "..." etc.
#endif

but this means you still need to provide .h support and thus lose all the benefits, plus your codebase looks quite ugly now.

If you do want to follow this approach, the easiest way to detect "CXX17_MODULES" which I just made up is to compile a small test program that uses modules with a build system of your choice, and define a global for everyone to see telling whether the compilation succeeded or not.

When starting a new project now, what should I pay attention to in order to be able to adopt the modules feature when it is eventually released in my compiler?

It depends. If your project is enterprise and gets you food on the plate, I'd wait a few years once it gets released in stables so that it becomes widely adapted. On the other hand, if your project can afford to be bleeding-edge, by all means, use modules.

Basically, it's the same story ast with Python3 and Python2, or less relevantly, PHP7 and PHP5. You need to find a balance between being a good up-to-date programmer and not annoying people on Debian ;-)

rr-
  • 14,303
  • 6
  • 45
  • 67
  • 1
    Why the downvote? Anyways, C++ modules are not yet another crazy ubercool feature, like user defined literals, but a well thought out solution to real problem (expressing modularity in C++ code). If my code is well designed, it is already modular. I just have to communicate it to the tooling, so that it can take advantage of it, – user7610 Apr 07 '16 at 21:23
  • I agree that we have to wait a while before it gets useable. I say 2025 it will be standart to use. The slow developed compilers from Oracle, IBM and Intel will be the main problem. Oracle still is at C++11 – Lothar Aug 05 '17 at 15:54