OR in version conditional compilation

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sat Mar 21 00:12:20 UTC 2020


On Friday, March 20, 2020 4:33:58 PM MDT jxel via Digitalmars-d-learn wrote:
> On Friday, 20 March 2020 at 21:03:55 UTC, Jonathan M Davis wrote:
> > On Wednesday, March 18, 2020 10:23:26 AM MDT IGotD- via
> >
> > Digitalmars-d-learn wrote:
> >> I have not seen any example where version has several OR
> >> matches.
> >>
> >> Example idiom:
> >>
> >> version(X86_64 || X86)
> >> {
> >>
> >> }
> >> else version(ARM || Thumb)
> >> {
> >>
> >> }...
> >>
> >> you get the idea. So is this possible at all or do you have to
> >> duplicate the code for each version identifier despite they
> >> are equal for many version identifiers?
> >
> > To add to what the others have said, the reasons that Walter is
> > against having boolean conditions in version statements have to
> > do with how using boolean conditions in #ifdefs in C/C++ has
> > historically been a big source of bugs. So, disallowing it
> > helps prevent certain classes of bugs. It's why druntime
> > duplicates most C declarations across platforms.
>
> What kind of bugs are those?

There are a variety of issues that come from it, and it's been discussed at
length in past threads (and much better than I'll explain here, I'm sure),
but the main issues stem from the fact that when you're writing code that is
platform-dependent but using it on multiple platforms, it can become really
easy to break stuff as the code is altered over time. e.g. you can make a
change that works perfectly fine on the platform that you're developing on
without realizing that it won't work on the other platforms sharing the same
#ifdef block, and while you should be testing such code on all supported
platforms, it often doesn't happen, and even when it does happen, it's
usually much further down the line after many more changes have been made.
It would be highly abnormal for someone to test what they're working on on
all of the relevant platforms as they're working on it.

It also can get really tricky to avoid subtle bugs once you start having
more complex boolean expressions and/or have nested #ifdefs. That's where
things tend to get _really_ bad. Another big problem comes in when you just
assume that the code from one platform will work with another and alter
existing #ifdefs to be used on the new platform. Suddenly code that was only
supposed to be used on one platform is being used on multiple, and it can
cause big problems depending on what that code actualy does and what
assumptions were made when writing it. By simply following the basic idiom
of

version(A)
{
}
else version(B)
{
}
else
    static assert(false, "Platform not supported");

you avoid problems that stem from code being used an a platform that it's
not intended for, and you get compilation errors if you try to use code on a
platform that it wasn't made to work on yet. It can result in more code
duplication than many people like, but it's ultimately less error-prone.
Either way, in general, it's far better to design your code such that as
little of it as possible is platform-dependent and that those parts that are
are well-encapsulated.

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list