No need for version expression is a lie

Walter Bright newshound2 at digitalmars.com
Thu Aug 24 16:47:55 UTC 2023


On 8/24/2023 8:30 AM, Adam D Ruppe wrote:
> On Thursday, 24 August 2023 at 04:53:49 UTC, Walter Bright wrote:
>> Can you be more specific? I'm curious.
> 
> version(unittest) made waves some time ago, making all kinds of random errors 
> when user code was trying to be tested but still imported phobos modules.

That was something different.


> I wrote at greater length about this here:
> http://dpldocs.info/this-week-in-d/Blog.Posted_2022_11_14.html#redesign-for-template-emission-woes

I'll read it, thanks.


>> Phobos has some head-scratchers, like this in std.stdio:
> 
> This specific one doesn't seem to make sense, but this pattern comes up a lot 
> because you might want to use a specific implementation from multiple triggers.
> 
> Easy to imagine there might be a CRuntime_DigitalMars and a 
> CRuntime_DigitalMars64, for example,

I wouldn't set it up that way. I'd version on IA64 within CRuntime_DigitalMars. 
I.e. overlapping version declarations are not a good plan, for precisely the 
reason you mention. Better to version along orthogonal axes.

> different predefined versions that share 
> the implementation of this portion. But other parts of the module might branch 
> differently on CRuntime_DigitalMars vs DM64, so you couldn't just find/replace 
> all if you decided to add the other one.
> 
> So the author there is probably doing this to try to future-proof the code with 
> some extra semantic tagging in case some other definition is added. I've done 
> this a few times myself.

Back in the 80s, everyone knew that 32 bits was inevitable. So the professionals 
future-proofed their code so it would be portable from 16 to 32 bits. (A classic 
example of this is Windows with their forest of typedefs like BYTE.) But when 32 
bits arrived, people discovered that their future-proofing did not work at all. 
It failed because none of them had ever ported code from 16 to 32 before, and so 
the future-proof solutions were all the wrong solutions.

The same thing happened to me.

But I learned how to make code 16->32 portable, and it was pretty simple. Just 
not at all like what I or anyone else presumed it would be.

Have you noticed how darned easy it is to port D code between 32 and 64 bit? 
That's the result of my experience porting 16 to 32.

The point is, future-proofing is a pretty hard thing to do, because we simply 
don't know what the future will be.

This is why I don't really try to future-proof with versions, instead relying on 
enumerating the known cases, and leaving the default with `static assert(0);`


> It actually isn't all bad, but it can get ugly when someone specifies 
> `-version=DIGITAL_MARS_STDIO` on the command line when building against 
> Microsoft C runtime... then what happens?

At some point, you're just going to have to run:

     grep -r version *

Fortunately (by design!) you can grep for such simple patterns. I learned that 
long ago when Matthew Wilson suggested I extend the DMC++ compiler to use a 
keyword for casting rather than (type) which is ungreppable, even with a regex. 
I put it in, but he refused to use it because no other C++ compiler did that and 
it wouldn't be portable.

I learned two things:

1. nobody wants local C++ extensions

2. the idea behind a keyword for cast was sound, and hence the D syntax which is 
easily greppable


> Or when someone again tries to figure proof and puts `else static assert(0)` at 
> the end, making incremental porting impossible. (which i also wrote about in the 
> last year: 
> http://dpldocs.info/this-week-in-d/Blog.Posted_2023_02_20.html#static-assert-patterns-arguably-harmful-for-porting )

I'll have a look at that.

> C's ifdef is a big mess.
> 
> D's version is a different big mess, but still a mess.

A much smaller one. I have a lot of experience with the C one. It's often 
essentially impossible to tell which path through the tangle is being taken 
unless one dumps the preprocessor output and examines it.

Even if one is faced with such a tangle in D, a strategic:
```
pragma(msg, "xyzzy");
```
will let you know which branch is happening. I sometimes resort to that with 
templates.



More information about the Digitalmars-d mailing list