8 ms·
While the author has WAY more knowledge/experience than me on this and so I wonder how he would solve the following issues: Evaluating Constant Expressions -
by chacham15 2y ago
While the author has WAY more knowledge/experience than me on this and so I wonder how he would solve the following issues:
Evaluating Constant Expressions
- This seems really complicated...if you're working within a translation unit, thats much simplified, but then you're much more limited in what you can do without repeating a lot of code. I wonder how the author solves this.
Compile Time Unit Tests
- This is already somewhat possible if you can express your test as a macro, which if you add in the first point, then this becomes trivial.
Forward Referencing of Declarations
- I think there may be a lot of backlash to this one. The main argument against this is that it then changes the compiler from a one-pass to two pass compiler which has its own performance implications. Given the number of people who are trying to compile massive codebases and go as far as parallelizing compilation of translation units, this may be a tough pill for them to swallow. (evaluating constant expressions probably comes with a similar/worse performance hit caveat depending on how its done)
Importing Declarations
- This is a breaking change...one of the ways I have kind of implemented templating in C is by defining a variable and importing a c file, changing the variable, and then reimporting the same c file. Another thing I've done is define a bunch of things and then import the SQLite C Amalgamation and then add another function (I do this to expose a SQLite internal which isnt exposed via its headers). All of these use cases would break with this change.
Are there any thoughts about these issues? Any ways to solve them perhaps?
- WalterBright 2y ago> if you're working within a translation unit, thats much simplified, but then you're much more limited in what you can do without repeating a lot of code. I wonder how the author solves this. You are correct in that the source code to the function being evaluated must be available to the compiler. This can be done with #include. I do it in D with importing the modules with the needed code. > This is already somewhat possible if you can express your test as a macro, which if you add in the first point, then this becomes trivial. Expressing the test as a macro doesn't work when you want to test the function. The example I gave was trivial to make it easy to understand. Actual use can be far more complex. > Performance D is faster at compiling than C compilers, mainly because: 1. the C preprocessor is a hopeless pig with its required multiple passes. I know, I implemented it from scratch multiple times. The C preprocessor was an excellent design choice when it was invented. Today it is a fossil. I'm still in awe of why C++ has never gotten around to deprecating it. 2. D uses import rather than #include. This is just way, way faster, as the .h files don't need to be compiled over and over and over and over and over ... D's strategy is to separate the parse from the semantic analysis. I suppose it is a hair slower, but it also doesn't have to recompile the duplicate declarations and fold them into one. Compile time function execution can be a bottleneck, sure, but that (of course) depends on how heavily it is used. I tend to use it with a light touch and the performance is fine. If you implement a compiler using it (as people have done!) it can be slow. > one of the ways I have kind of implemented templating in C is by defining a variable and importing a c file, changing the variable, and then reimporting the same c file. Another thing I've done is define a bunch of things and then import the SQLite C Amalgamation and then add another function (I do this to expose a SQLite internal which isnt exposed via its headers). All of these use cases would break with this change. I am not suggesting removing #include for C. The import thing would be additive. > Are there any thoughts about these issues? If you're using hacks to do templating in C, you've outgrown the language and need a more powerful one. D has top shelf metaprogramming - and as usual, other template languages are following in D's path.
- daymanstep 2y agoCan't you use precompiled headers?
- WalterBright 2y agoInteresting you brought that up. I implemented them for Symantec C and C++ back in the 90s. I never want to do that again! They are brittle and a maintenance nightmare. They did speed up compilations, though, but did not provide any semantic advantage. With D I focused on fast compilation so much that precompiled headers didn't offer enough speedup to make them worth the agony.
- fuhsnn 2y ago>They are brittle and a maintenance nightmare I happened to be reading DMC source this week, those hydrate/dehydrate stuff really is everywhere (which I assume is solely used for precompiled headers?)
- WalterBright 2y agoYup. I spent a crazy amount of time debugging that. The tiniest mistake was a big problem to find.
- ndesaulniers 2y agoI had an intern try to use precompiled headers for the Linux kernel. The road block they found was that the command line parameters used to compile the header must exactly match for all translation units which it is used. This is no the case for the Linux kernel. We could compile the header multiple times, but the build complexity was not something we could overcome during the course of one internship.
- WalterBright 2y ago> must exactly match Yup. My compiler kept a list of which switches would perturb compilation and so would invalidate the precompiled header, and which did not. Precompiled headers are an awful, desperate feature. Good riddance.
- xigoi 2y agoI personally don’t like forward referencing because it makes code harder to read. You can no longer rely on the dependency graph being in topological order.
- WalterBright 2y agoAs the article writes, that forces the private leaf functions to be at the top, with the public interface at the end of the file. The normal way is the public interface at the top, and the implementation "below the fold", so to speak. > topological order You are correct. But its the reverse topological order, which is not the most readable ordering. One doesn't read a newspaper article starting at the bottom.
- xigoi 2y agoMaybe it’s because I’m primarily a mathematician, but I like building complex stuff up from primitives and having the most important results at the end.
- WalterBright 2y agoVive la différence - and you'll still be able to do it your way!
- kccqzy 2y agoThat's not how I do things in math. I always need motivation first. So I start with the theorem, look at a couple of examples to see why this theorem is interesting, and then the various lemmas leading into the proof. So that means I really like declaring but not defining the public interface first, and then define the private helper functions, and finally definitions for the public interface.
- Lvl999Noob 2y agoPerhaps the difference is having algorithm in your head and just putting it into code, versus only knowing the top level work to be done and implementing the needed operations later. If I am writing some kind of service, I would write the main public functions first, using undefined functions in their bodies as needed. Then I would implement those functions below.
- billfruit 2y agoEvery other language does seems to not require header file/forward declarations. I don't understand the backlash against that. Are modern C compilers actually still single pass?
- WalterBright 2y ago> Are modern C compilers actually still single pass? All except ImportC, which effortlessly handles forward references. (Mainly because ImportC hijacks the D front end to do the semantics.)
- UncleEntity 2y agoA bit of an aside but I was poking around in the SPIR-V spec yesterday and they can do forward references because the call site contains all the information to determine the function parameter types. Just thought it was interesting and not really something I had thought about before.