'version'-based code selection

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sat Jun 1 07:46:40 UTC 2019


On Friday, May 31, 2019 9:59:13 PM MDT Yatheendra via Digitalmars-d-learn 
wrote:
> Hi people.
>
> The 'version' keyword sounds like a fantastic capability, but how
> far does DMD take it (and does GDC take it equally far)? This is
> not a "D Improvement Proposal", I am just asking how it is now.
>
> Can code of multiple versions be compiled into the same
> executable or library, and a particular one selected from
> "later"? I guess not without some name mangling and wrangling.
>
> Can such selection be done at link-time for standard as well as
> user-defined library code? Maybe some library file naming
> conventions are followed to allow the compiler to select the
> corresponding file?
>
> Wishful thinking, but can the selection be at runtime? That would
> be language support for making some things easy, e.g. picking
> from assembly-coded routines based on runtime CPU id (the video
> player MPlayer picks routines that way, and I read that the D
> library, Mir, has CPU id support).
>
> Thanks.
>
> P.S: I am a brand-new C++'y asylum seeker who may have missed
> seeing some documentation, so RTFM is a valid response.
>
> P.P.S: This question was triggered by the D GSoC project for
> independent-of-C implementations of malloc/free/memcpy/memset.
> Could a common malloc be exposed to the D
> runtime/Phobos/programs, with the C or D implementations
> selectable at link-time (using a mechanism available to user code
> too)?

Like static ifs, version statements are completely a compile-time construct
and having nothing to do with runtime beyond how they affect the code that's
generated. They also have nothing to do with linking beyond how they affect
what code is generated.

version statements are basically just static if statements that are compiled
in if the corresponding version identifier has been defined. They're
esentially D's answer to C's #ifdefs. A version statement can only check a
single version identifier (so, no boolean logic like with #ifdefs), but else
can be used like with static ifs. e.g.

version(linux)
{
    // compile in this code on Linux
}
else version(Windows)
{
    // compile in this code on Windows
}
else
    static assert(false, "This platform is not supported.");

Multiple version identifiers exist when compiling. For instance, if
compiling on 64-bit x86 Linux, both the linux and X86_64 version identifiers
would be defined. So, it's not like there's only one version identifier when
compiling. Additional version identifiers can be supplied on the
command-line when compiling, and you can even define a version for just
within the module (version identifers cannot be imported). You don't
technically need to compile each module in a program with the same set of
version identifiers, but it's usually asking for trouble if you don't,
because that can cause problems when a module is imported using one set of
version identifiers but actually compiled with another (e.g. totaly
different symbol definitions could be used depending on what was versioned
in the module, leading to linker errors).

For the most part though, you don't declare your own version identifiers. It
sometimes makes sense, but usually, version identifiers are used for
versioning code based on the platform or architecture that it's compiled on.
They're really only intended to be a saner version of #ifdefs, and if you're
doing anything fancy with them, you're really not using them as intended and
are probably going to have problems.

The list of predefined version identifiers can be found here:

https://dlang.org/spec/version.html#predefined-versions

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list