
Constexpr-8cc: Compile-time C Compiler - santaclaus
https://github.com/kw-udon/constexpr-8cc
======
wcrichton
If you're interested in _sane_ staged metaprogramming:

Lightweight Modular Staging (Scala): [https://scala-
lms.github.io/](https://scala-lms.github.io/)

Terra (Lua): [http://terralang.org/](http://terralang.org/)

Compiler Plugins (Rust): [https://doc.rust-lang.org/book/compiler-
plugins.html](https://doc.rust-lang.org/book/compiler-plugins.html)

~~~
minxomat
Some more insane on the other hand, using {order,chaos}-pp: [http://chaos-
pp.cvs.sourceforge.net/viewvc/chaos-pp/order-pp...](http://chaos-
pp.cvs.sourceforge.net/viewvc/chaos-pp/order-
pp/example/bottles.c?revision=1.10&view=markup)

------
ivoras
I feel like C++ is moving towards being as useful as a brick. You get a brick
and you ask yourself "what can I do with it", and the answer is "everything!
absolutely anything!" Then you ask yourself "how?" and the answer is 3000
pages of standards, activities and rules on how to actually use a brick to
make truly anything, with 800-page addenums to using boost-brick (i.e. some
mortar).

~~~
kazinator
I agree with you. If you can't get the job done using _mostly_ that language
described in the Brown Book ( _C++ Annotated Reference Manual_ by B.
Stroustrup and Margaret Ellis), plus a judicious smattering of some newer C++
ranging from C++98..C++03 (at most), you should fucking retire.

The last useful change in C++ was (circa 2006?) making string literals const.
That's it.

~~~
andrepd
Oh brother...

What about: lambdas, type inference, tuples, robust templates, compile time
constants and code execution, move semantics, expanded PoD, initializer lists,
range based for loops, user literals, return type deduction... I could go on
and on. All features I use _daily_. And I'm not even getting into C++17.

~~~
kazinator
Half-broken, bolted-on garbage that is found in a much nicer form in high
level languages which have those things in their _core vision_ from the
beginning, or the kind of extensibility which can cleanly support new ideas.

> _And I 'm not even getting into C++17._

I'm with you there, in a way.

~~~
matthewaveryusa
I don't find auto, lambda, and variadic templates, move semantics and smart
pointers to be bolted on. You can write Fortran in any language.

~~~
Retra
You think rvalue references are a natural and elegant construct? That if C++
were designed with move semantics in mind, this is the road they would have
travelled down?

~~~
kinghajj
That's the biggest reason that I like Rust more than C++, even more than
lifetime/safety. I've been working on a C++14 application, and "std::move"
shows up a lot more than implicit copies, which not only makes the code more
verbose, but analyzing performance more difficult. (I _so_ wish I could be
using Rust, but, unfortunately, the only FOSS DNP3 implementation is in C++.)

------
haberman
I found the README confusing. Basically it appears to compile C -> ELVM IR all
in C++ constexpr. Doing this requires preprocessing the input file into a
string inside the C++ source file. The result is that ELVM IR is embedded as a
string inside the output binary, and running the output binary does nothing
but dump this compile-time-computed string.

------
gghh
Am I correct in understanding that, contrary to the Turing completeness of C++
template instantiations, the (compile time) computational power of these
Constant Expressions thing is intentional?

~~~
JoshTriplett
Yes. A "constexpr" function can use a large subset of C++, including calls to
other constexpr functions, but the compiler guarantees to evaluate it at
compile time, so you can use it where the compiler expects a compile-time
constant.

~~~
zmodem
> the compiler guarantees to evaluate it at compile time

It doesn't guarantee that.

For example:

    
    
      static constexpr int fac(int x) { return x <= 1 ? 1 : x * fac(x - 1); }
      int f() {
        return fac(4); // May or may not be evaluated at run-time.
      }
      char arr[fac(4)]; // fac(4) is evaluated at compile-time.

~~~
JoshTriplett
I should have said, "guarantees that it _can_ evaluate it at compile time if
needed, such that you can use it where the compiler expects a compile-time
constant expression". Yes, the compiler can choose to defer it until runtime
in some cases.

~~~
euyyn
Can it be forced to be computed at compile-time, by static_assert'ing on the
result of the computation?

~~~
gpderetta
Yes, among other things. As long as a program can't tell the difference (as
per the as-if rule), the compiler is free to delay tjee evaluation till
runtime.

------
wsmith
_by relaxing constrains, constant expressions became so powerful that a C
compiler can be implemented in!_

I wonder how long it will take before C++ accidentally becomes a Lisp.

~~~
knome
C++'s template system is more of a dynamically typed Haskell.

~~~
xwvvvvwx
This video (from the amazing Bartosz Milewski) does a great job of
illustrating this:

[https://vimeo.com/7211030](https://vimeo.com/7211030)

------
amluto
Now someone just needs to write a constexpr ELVM interpreter and teach 8cc to
compile C++14 and this whole thing will self-host!

------
munificent
Don't most C compilers compile C at compile time? That's what makes them C
compilers.

~~~
pwdisswordfish
This C compiler is compiled at the same time the C compiler compiles your
program. In other words, it compiles C at compiler compile time, where with
other C compilers the program's compile time is the compiler's run time.

Hope this helps.

------
__s
See also ELVM's resulting vimscript 8cc:
[https://www.reddit.com/r/vim/comments/58hm9n/8ccvim_c_compil...](https://www.reddit.com/r/vim/comments/58hm9n/8ccvim_c_compiler_written_in_vim_script/?st=ivodyglz&sh=2d0b0580)

Machine generated vimscript.. so gross

------
the_duke
While pretty useless, this is bloody hilarious work!

