4 ms·
Indeed. You've now taken one solution off the table. The other one is for the build system to become a compiler, which is equally unacceptable. That leaves you
by jsnell 8y ago
Indeed. You've now taken one solution off the table. The other one is for the build system to become a compiler, which is equally unacceptable. That leaves you with manually encoding all dependency information in the build files. Which most people aren't doing (the exception being Bazel-like build systems which enforce that).
That seems to leave us with just one conclusion: the article is right, and most of the ecosystem will never migrate to modules, leaving us with the worst of both worlds.
- ginko 8y agoThe build system doesn't need to become a compiler. It just needs to parse the source files for import statements in order to create a DAG.
- ZirconiumX 8y agoBut you also need compatibility with #include, so your build system also needs to become a preprocessor.
- ginko 8y agoThe preprocessor is a self-contained binary. The build system can just pipe through it.
- gchpaco 8y agoThe C and I presume C++ standard has been very carefully avoiding the idea of a preprocessor being separate at all. The standard was very carefully worded to prevent that being necessary, because most C compilers do not have a separate preprocessor. It is only Unix heritage compilers that really have one, and even they're not consistent about it.
- ZirconiumX 8y agoI'm curious how you plan to detect dependencies from a file by piping it through a command that removes those dependencies.
- jcelerier 8y ago> The build system doesn't need to become a compiler. It just needs to parse parsing C++ is mostly equivalent to becoming a C++ compiler.
- geezerjay 8y ago> parsing C++ is mostly equivalent to becoming a C++ compiler. It reallt isn't. Parsing a languagr just means validating its correctness wrt a grammar and in the process extract some information. Parsing something is just the first stage and a one of many stages required to map C++ source code to valid binaries.
- tcbrindle 8y agoThe presence of template specialisations and constexpr functions means that the GP is right here; you cannot decide whether an arbitrary piece of C++ is syntactically valid without instantiating templates and/or interpreting constexpr functions. Consider template <int> struct foo { template <int> static int bar(int); }; template <> struct foo<8> { static const int bar = 99; }; constexpr int some_function() { return (int) sizeof(void*); }; Now given the snippet foo<some_function()>::bar<0>(1); then if some_function() returns something other than 8, we use the primary template and foo<N>::bar<0>(1) is a call to a static template member function. But if some_function() does return 8, we use the specialisation and the foo<8>::bar is an int with value 99; so we ask is 99 less than the expression 0>(1) (aka "false", promoted to the int 0). That is, there are two entirely different but valid parses depending on whether we are compiling on a 32- or 64-bit system. Parsing C++ is hard. EDIT: Godbolt example: https://godbolt.org/z/yR3YHW https://godbolt.org/z/yR3YHW
- ginko 8y agoYou only need to parse the "module <module name>" and "import <module name>" statements. No need to parse all of C++ for that. You could probably even do that with a regex.
- 8y ago
- humanrebar 8y agoOr do the modules equivalent of 'g++ -MM'. Or is there some reason we wouldn't want that approach?
- jsnell 8y agoThat's the problem: you can't do that. Having the compiler produce header dependency information is possible, since the dependencies are just an optimization. If there's no dependency information available, you can just compile all of the files in an arbitrary order, and you get both the object file and a dep file. And then on further runs you use the old dep files to skip unnecessary recompilations. With modules, you can't compile the files in an arbitrary order: if A uses a module defined in B, B must be compiled first. So you need to have the dependency information available up front even for the first build. And since it needs to be available up front, it can't be generated by the compiler. It must either be produced by the build tool which becomes vastly more complicated, or manually by humans.
- coliveira 8y agoThis is not different from a situation where C++ compilation has a binary dependency on other modules. The best know situation is a static library (.a file). In this case, the project cannot be built if there is a static library missing. With modules, one cannot compile the project with missing modules, so the build system will have to provide this information.
- coliveira 8y agoYour conclusion is incorrect. Most people with simple projects will use simple techniques to make modules work without worrying about the preprocessor. Large companies will create their own tooling to use modules in their own way. My point is that this is how C++ has been used since its inception. C++ users are already aware that the language needs external building support and modules cannot change this reality. But modules will certainly improve how the language is used.