Not exactly. D is going the route of actually implementing a C compiler in the D compiler. Here's the C parser:
https://github.com/dlang/dmd/pull/12507/files#diff-2fc171ca9...
You could argue that writing a C compiler instead of using libclang is an indicator of brain-damage, but I lay out my reasons here:
https://digitalmars.com/d/archives/digitalmars/D/Add_ImportC...
And besides, C is such a simple language it's kinda fun.
> I wouldn't be surprised that the eventual cost of adapting ourselves to
> libclang will exceed the cost of doing our own C compiler.
This is a really insightful point. I had to learn this the hard way :)
We might follow your lead on this, as we have done with so many other great ideas implemented in D.
Ironically, Vexu started from the other side as you, with the preprocessor mostly done, but the backend left to-do: https://github.com/Vexu/arocc
One thing that might make libclang worth the cost, however, is its ability to compile C++ code as well. On Zig's end of things, all we have to do is provide libcxx, libcxxabi, libunwind, compiler-rt, and linking, and then libclang is really pulling a lot of weight by compiling C++ code into object files. Sadly this ability is just too useful in practice to ignore. For example, LLVM itself is C++ so if Zig wants to be able to bootstrap itself, it needs this capability.
Still, I think your maneuver here is the best long-term approach to tackle this problem, and I imagine as time goes on we'll start to migrate towards D's solution here. Maybe someday the Zig distribution that does not have LLVM extensions enabled will be the more popular one.
I'll be watching the evolution of this new feature in D with great interest!
1. Even though I have written a C++ compiler, it's a C++98 compiler and C++, like the Winchester House, accretes new features constantly, meaning keeping it up to date is impractical.
2. C++ semantics are different enough from D that it is impractical to mechanically map C++ to D. You can do bits and pieces, and dpp does that, but seamlessly doing the bulk of it isn't going to work. (C can be mapped nearly 100% to D.)
dpp uses libclang to try and map what it can to D.
echo hello.c
int printf(const char*,...);
int main() { printf("hello world\n"); }
dmd hello.c
./hello
hello world
But then there's the question "should D features be allowed in the C code?" This is a very subversive question. Is it really C if that is allowed? Already, the C code allows for Compile Time Function Execution, which comes for free by passing the C code through the D front end. You can see it in action in the test cases in this file:https://github.com/dlang/dmd/pull/12507/files#diff-b94776a02...
Scroll down a bit and you'll see it executes C functions at compile time. I decided to flirt with heresy and leave this in, because it sure makes adding tests convenient!
I'm less sure about adding unittests to the C compiler. Certainly, you can always add the unittests to the D code that is importing the C code. This will probably hold the charges of abomination to a minimum.
Oh my good gosh. D and C could be seamless together. This is great.
> I decided to flirt with heresy and leave this in
I'd love to see more C language extensions in ImportC.
It's not bolted in the compiler so less nice than Zig but the jar produced by jextract is not ABI dependent so more portable. The ABI dependent code is generated by the JIT using the the Foreign Linker API (the equivalent of C# DllImport) at runtime.
https://docs.microsoft.com/en-us/previous-versions/visualstu...
Unfortunately there's a lot of disagreement between the bigger players as to how this should be handled:
> > 1) The authors appear to be deadlocked
> No need to soften it with an "appear", we are intractably deadlocked.
to bystanders, odd autocorrect: it's marshalling. marshalling data. although fight and war are indeed also appropriate associations for binary data exchange (struct conversions) between languages.
Marshal = mariscalcus = "horse servant", compare mare and seneschal. Martial = from Mars, god of war.
these CS gals of olde really had a hand for naming :-)
Not mocking the spelling of the previous post; it's a strange term anyway and in this instance either spelling works.
You can absolutely set up a cross-compiling C/C++ toolchain today as he said - but you're going to have to find the right packages in your distro, deal with the MacOS linking issue, get a copy of the android NDK, make sure you're installing the right package versions, muck around with libc, etc. That doesn't make for a delightful start to a new weekend project.
It's often underestimated just how substantial "setup pains" are IMO. I suspect most people who have a strong distaste for C/C++ mostly despise the tooling and installation hell.
The novel part of what Zig, (and maybe Rust/Go to a lesser extent) are doing with cross-compilation is not 'making cross compilation possible' - it's having 'the best experience' out of the box, with zero installation pain.
Zig has a ton of issues and is super early stages still.
But shipping out-of-the-box with a Zig/C/C++ cross-compiler, with libc, static libc(musl), compiler-rt, libunwind, libcxx, etc. for ~50 cross-compilation targets, and solving the MacOS cross-compilation linking issue (with their customer linker, zld) is IMO a huge deal because it lowers the barrier to entry to systems programming quite substantially.
For me the best example I currently have of such attitude is how an internal WinDev group managed to push for getting C++/CX replaced with C++/WinRT without it being production ready.
After 4 years, still no Visual Studio support for IDL files, one has to manually copy/merge generated files into the Visual Studio project, no two way editing with XAML files, we get continuously told that it only will be fixed when ISO C++ gets compile time reflection.
Apparently they feel that is a productive experience and never came close to try out either C++ Builder or QtDesigner.
I guess they were still using raw C to deal with COM to consider this kind of downgrade as something positive.
* specifying target cpu features (important!)
* features such as thread sanitizer support
* LTO that crosses the libc boundary
* targeting any glibc version
...all of which are supported out of the box by zig.
An added benefit is you get ffi-reflect -- https://github.com/corsix/ffi-reflect -- over the resulting types / functions...
Despite being told numerous compile-time options to use by different manuals and documents and people on IRC, nothing appeared to change the outcome. It might be due to some undefined behaviour in bzflag, of course, but it made zig cc a non-starter for C.
https://github.com/ziglang/zig/issues/4830#issuecomment-6054...
I saw this addition in zig and thought that it was amazing, a lot of languages have this need to create definitions in their own language, C# with [DllImport](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.i...), [crystal with lib](https://crystal-lang.org/reference/syntax_and_semantics/c_bi...), I think since C is so ubiquitous and being able to just consume header files just removes so much boilerplate creation that is easy to get wrong.
zig also decided to just call an existing compiler (clang) and if you do zig cc --version then zig thinks it is clang, because the zig compiler just calls into clang main. D has gone with the route of calling gcc.