Hi,
Post by Klaim - Joël LamotteThe way modules have been done, they require the sources files to declare which module they implements and what they exports into a preambule.
To be honest, I don't really get why this was necessary.
My understanding is that the main reason is that it helps tools know
the dependencies without having to parse the rest of the C++ syntax.
Build systems will have to check every source file in a first pass to
quickly decide what have to be built, by making a dependency graph.
This pass is simple if the information is easily locatable and with
always a strict subset of possible C++ syntax.
- The dependency graph could be quite hard to compute and will require to parse every source files. While this is viable on small projects, this could (and probably will) be a problem on large ones.
So far build2's main author reports no problem with this, as long as
the preamble is easilly parsable without having to have a complete C++
parser.
Also it seems to help making the rest of the compilation process faster.
I have some hello world using modules if you want to try them as a
starting point for converting a library and see if you see
improvements?
- So far, dependency have always been computed from the build system itself, by specify which files are part of a library, and what other libraries are needed to create each one of them.
That part do not change as module have nothing to do with the
dependency graph at the link level.
Basically this is the opposite approach where this information is described in the build system and is not know by the sources files. And so far, I do believe this model works well and doesn't require to be changed.
I think you're mixing the end result programs (exes, dlls/so, static
libraries) with modules. A C++ language module have nothing to do with
the actual generated binaries. It's code compartmentalization mainly.
You can have 10 modules in one so or in one exe, or in a
module-interface-only library (like a header-only library).
Also, the way you phrase it seem to indicate we're modifying the language to help other tools (not compilers) to deal with it. I hope it's not the case.
Modules add to the language, it doesn't "modify" the current one.
Tools are handicapped by the current include system.
Why would it be not the case? How do you want something like an IDE
extension trying to deduce where the words in the line you're pointing
to are from? They need to know the dependencies of the context.
Also the main tool that this helps is build systems, that can then
easily expose the dependency graph (of modules, not of binaries, which
they already do).
Post by Klaim - Joël Lamotte- It makes sources files dependent on which modules they will be shipped in.
I'm not sure I understand this point.
Isn't it the point of modules to associate a module name to sources?
I don't think so.
I think the point here is how to export the functions, global variables, ... in a more efficient way than using header files (eg: by avoiding to parse and reparse the same code every times an header is included).
Here in the context of modules, "export" means "making these names
visible to the importer", it does not mean something like dllexport.
Just clarifying because the way you point this is weird to me, in this context.
Other than that I agree with you and it seems to do exactly that:
modules are compiled once. The preamble pre-reading to build the
modules dependency graph is trivial compared to what is needed to
parse the language for compilation.
Note that after reading http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4047.pdf, it seems they also speaks about "componentization", but i'm usure the current proposal is the best way to achieve it (exporting or not a symbols can for example already be specified using the visibility attribute when using clang/gcc).
Modules do nothing to symbols. They componentize names.
If you want to export symbols, as in making a function in a .so/,dll
usable by another program, you stil have to add some dllexport/import
macros as it have nothing to do with modules.
I have an example here where I use some import/export macro
(symexport) in addition to a module export:
https://github.com/Klaim/build2-libhelloworld-exe-modularized/blob/master/libhelloworld-modules/helloworld-modules.mxx
(The syntax is the one implemented in VS 15.9 so it's Modules TS
syntax, not more recent Module proposal version).
Note that there is another proposal for a library API for helping with
plugins. But again this have nothing to do with modules.
Post by Klaim - Joël Lamotte- Not only the sources does declare the module they belongs to, but they also need to be put together in the build system (may it be Makefiles, cmake, ...). This goes against the DRY concept since it cause duplication of information.
I don't understand where would be a duplicate information. The module
names exist only in sources, not in build system's project description
files (at least in any decent build system).
As said above, this is basically the opposite approach.
Again I think you're mixing binaries dependencies and modules (as in
code-only) dependencies.
By the way why do we need to put your files together in the source code inside a module while we already put them inside the same library or executable at the build system level?
The basic idea is that it depends on how you like to organize your
code. Modules are designed to not get in your way with this.
So if you want to have all the code in one module file (which then is
the module interface, with a public eported part, and maybe another
part not exported), nothing prevent you to do so.
If you want to splitt 1 Module into say 10 source files, you have
different ways to do so. The main thing is that at the end there is
only one file that defines what the module exports.
If you want to splitt your module in several modules then make one of
the module export the others, you can also to that.
If you want to have only the module interface containing exported
names, and all the other source module files having the definitions,
you can.
Etc. Organize as you want, the only constraint is that for one module,
there needs to be one file that will export the names for importers.
The details of how to do these is longer to explain but I think
several talks and papers can help with that.
Again, this have nothing to do with the binary linking part of the
process of building programs, so you can have 10 modules in a .so or
in a exe if you want.
Post by Klaim - Joël Lamotte- There is a concept of 'module interface unit' (and even a 'primary module interface unit'!). As far as I understand it, it is almost the same that old .h files, thus providing no real benefit over the latter when writing new code.
Of course it provides benefit! It's like saying that a header file and
a module is similar, but it's really not. For example, your header
will leak it's names into user's user's code. Modules will not by
default.
The point of these interface unit is to allow you to not change the
interface but change the implementation without the user aving to
recompile their code, even if all the module code is defined in one
file.
The interface/implementation separation is already there when using header files, so what you describe here seems to me already possible.
I'm not sure to get your point here.
Ok, to clarify: it's kind of the same idea but done in a different way
which removes the issues with headers.
Among numerous issues, headers (assuming with only interfaces exposed
in them), cannot guarantee independence of what they expose.
#include "aaa.hpp" // void foo(Bar b);
#include "bbb.hpp" // #define Bar Kikoo
Can give a different code than
#include "bbb.hpp" // #define Bar Kikoo
#include "aaa.hpp" // void foo(Bar b);
Here both headers interract because in the end their content only
exist in the cpp including, so they impact each other.
You can try to make sure that your headers will always produce
equivalent code whatever the the other includes around (we call these
"well behaved" and there is a proposed mechanism
to help use them as if they were modules), but you are still dependent
on them and external ones because just one header could redefine any
word used in the following header included (mainly through macros).
With modules:
import aaa;
import bbb;
and
import bbb;
import aaa;
Are stictly equivalent, by design, whatever is define in these
modules. Importing one will not change the other as macros are simply
not imported, and only names/signatures can be exported.
Because this is only importing names from these modules in the set of
possible names that could be found when you try to use a name.
But you are right that in essence the module interface solve the same
problem (better) than having headers with only interfaces
declarations/definitions.
Post by Klaim - Joël LamotteAs you can see, it's a fix of the preamble, not a removal.
Yes, unfortunately.
I'm not sure what is the problem with the preamble exactly? Did you
want to import from another place?
Thanks for your answer,
No problem. :)
Joël
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOU91ONR5v9ujCaM5Riu5Dc39cejV4VcMEdieF3O6b_edy%2BY7g%40mail.gmail.com.