Fear of Compiler Magic
Dennis
dkorpel at gmail.com
Fri Aug 2 09:29:30 UTC 2024
On Friday, 2 August 2024 at 03:22:28 UTC, IchorDev wrote:
> And besides that, isn’t ‘compiler magic’ at its logical
> conclusion generally applicable to *any* task performed by the
> compiler? Exception handling, code optimisation, inlining,
> template expansion, `new`, adding two numbers? Compiler magic.
A good programming language consists of a small set of orthogonal
features that combine into a powerful language. Magic features
are situational. They add the maintenance burden of an orthogonal
feature, but instead of multiplying the language's
expressiveness, they only add a constant to it. So what happens
in practice when you pile on magic features?
To keep technical debt of large code bases under control,
refactoring needs to happen. Refactoring relies on performing
code transformations that result in equivalent semantics. As a
programmer, you want to have actions you can always do safely,
based on general facts:
- Comments don't affect code
- Unreachable code can be removed
- Function definitions can be moved around
However, proposals for magic features tend to add more and more
exceptions. I have seen proposals that would make `version(all)
assert(0);` not always equivalent to `assert(0);`, or `x + 1`
different from `x + (1)`. And most recently: [Make printf
safe](https://forum.dlang.org/thread/v6uolo$22e4$1@digitalmars.com).
You would think it's safe to transform this:
```D
printf("x = %s\n", x);
printf("x = %s\n", x);
```
Into this:
```D
const(char)* fmt = "x = %s\n";
printf(fmt, x);
printf(fmt, x);
```
But with magic printf format string rewrites, that transformation
turns correct code into memory corrupting code when x is an int.
This doesn't mean magic features are always a bad idea. The
`__FILE__` and `__LINE__` tokens are somewhat magical, and they
break all the aforementioned refactoring equivalences, since any
code movement (including comments!) can alter line numbers, which
potentially alters the meaning of the program.
In practice of course, `__FILE__` and `__LINE__` are not used for
control flow, only for logging, so it's not a big problem. But
hopefully you see why many people are very wary of magic
features, lest the language becomes a minefield of gotchas like
the printf example.
p.s. It even used to be the case that `__LINE__ + 0` was not the
same as `__LINE__`!
(https://issues.dlang.org/show_bug.cgi?id=18919)
More information about the Digitalmars-d
mailing list