Conditional Compilation Multiple Versions

Claude via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jan 6 02:25:26 PST 2017


On Thursday, 20 October 2016 at 09:58:07 UTC, Claude wrote:
> I'm digging up that thread, as I want to do some multiple 
> conditional compilation a well.

Well I'm digging up that thread again, but to post some positive 
experience feedback this time as I've found an answer to my own 
questions, and I thought I could share them.

I wanted to convert some C preprocessing code to D: thousands of 
conditional compilation macros #ifdef, #if defined() used in a 
program that determine the capabilities of a platform (number of 
CPU cores, SIMD availability, etc). So it had to check compiler 
types and versions, combined with the target architecture, and 
the OS, and the endianess and so on.

So the C implementation is a stream of:
#if defined(MYOS) || defined(ARCHITECTURE) && 
defined(__weirdstuff)
# define SPECIFIC FEATURE
#else
# blabla
...

And I though I would have to use some || and && operators in my D 
code as well.

So I did. I used that trick from Mike Parker and anonymous (see 
above in the thread) by declaring "enum bool"s to be checked with 
"static if"s later to implement specific feature.

So I had a stream of:

version (Win32)
   enum bool WindowsSupported = true;
else
   enum bool WindowsSupported = false;

version (Win64)
   enum bool WindowsSupported = true; //Ooops
else
   enum bool WindowsSupported = false; //Ooops

It turned out to be not so readable (even when using a "string 
mixin" to make the code tighter), and I cannot define twice an 
enum without using "static if", which was a deal-breaker. Also 
the conciseness of the versions for the D compilers (only 4: DMD, 
GDC, LDC and SDC), as well as the different OS versions made the 
code a lot tighter than the C version.

So I just dropped the enum definition thing and just used 
"version" as it was designed to be used:

version (Win32)
   version = WindowsSupported;
else version (Win64)
   version = WindowsSupported;
else etc...

So to my older question:

> * Is there an "idiomatic" or "elegant" way of doing it? Should 
> we use Mike Parker solution, or use the "template 
> Version(string name)" solution (which basically just circumvent 
> "version" specific limitation)?

That little experience showed that using version as it is 
designed currently is enough to elegantly cover my needs. And it 
seemed to scale well.
Also I think it may force developers to handle all version 
specific stuff into one specific module and define your own 
version identifiers to list features from compiler, OS, target 
architecture version identifiers; which is a good coding practice 
anyway.

So:

module mylib.platform;

version (ThisOs)
  version = ThatFeature;
else
  version = blabla;
etc...

And:

module mylib.feature;

void doFeature()
{
version (ThatFeature)
   blabla;
}

But again, that's just my feedback from one single experience 
(even though I think that kind of code is quite common in C/C++ 
cross-platform libraries).

So I'm still curious as why Walter designed "version" that 
particular way, and if anyone has bumped on "version" 
(quasi-)limitations and what they think about it!



More information about the Digitalmars-d-learn mailing list