No need for version expression is a lie

Adam D Ruppe destructionator at gmail.com
Wed Aug 23 17:24:24 UTC 2023


On Wednesday, 23 August 2023 at 17:09:09 UTC, Walter Bright wrote:
> That's deliberate, because the Bob and Carol versions should 
> not co-exist in the same executable.

Well, they do anyway. And then you get random name conflicts 
across different libraries.

lib a uses version(fast) to do something. lib b uses 
version(fast) to do something different.

dmd -version=fast affects lib a and b together.

So then people get clever and do

dmd -c -version=fast liba.d
dmd -c libb.d
dmd liba.obj libb.obj main.d

now version fast and non-fast can exist together, since the 
separate compilation gave a bit of isolation. But...

---
module liba;
struct A {
    version(fast)
        int a;
    int b;
}

void foo1(A b) {}
// --------
module libb;
struct B {
    version(fast)
        int a;
    int b;
}

void foo2(B b) {}
---

And then you

---
import liba;
import libb;

void main() {
      foo1(A(4));
      foo2(B(4));
}
---


and guess what? things explode since now there's an abi mismatch. 
There is no way to compile the main module to use both the 
precompiled liba and libb together (except writing new bindings 
that match the abi by hand, of course you could do that).


This kind of thing has happened even with Phobos.


D's `version` specifier is a major failure in real world code, 
leading to incomprehensible soup in addition to runtime 
corruption, porting trouble, and other problems.

C's system sucks, but D's does too, in ways that are not as well 
known as C's.

> You can also create a config.d file with a list of enum 
> declarations in them, import that, and use whatever algebra you 
> want with static if.

This is *significantly* better than using D's failed `version` 
specifier.


More information about the Digitalmars-d mailing list