Thread overview
Inversion of conditional compilation statements
Dec 02
user1234
Dec 02
ryuukk_
Dec 02
ryuukk_
December 02

Hello,
I am trying to learn D and I have stumbled upon an issue
Consider this code:

import std.stdio;

//version = Test;

int main() {
        version (Test) {
                writeln("Hello, world!");
        }
        return 0;
}

This compiles, however what if we want to turn the version statement around?
I first expected version (!Test) to work, but it doesn't since the grammar says:

VersionCondition:
    version ( Identifier )
    version ( unittest )
    version ( assert )

We are using the first way, the one with the Identifier.
The reason inverting works with if-statements is because they take an "Expression".

I see the way why it doesn't work, but I think it should. Considering that
version (Test) {} else {
works without any issue but looks very ugly.

Can somebody explain if this is an intended decision or what I should do instead of using my ugly replacement?

December 02

On Saturday, 2 December 2023 at 13:16:26 UTC, Johannes Miesenhardt wrote:

>

Hello,

[...]

I see the way why it doesn't work, but I think it should. Considering that
version (Test) {} else {
works without any issue but looks very ugly.

Can somebody explain if this is an intended decision or what I should do instead of using my ugly replacement?

It's an intended decision that's often debated, a.k.a "version algebra". The official position on version algebra is that complex conditions (think && and ||) would be a source of bugs.

December 02

On Saturday, 2 December 2023 at 13:16:26 UTC, Johannes Miesenhardt wrote:

>

Hello,
I am trying to learn D and I have stumbled upon an issue
Consider this code:

import std.stdio;

//version = Test;

int main() {
        version (Test) {
                writeln("Hello, world!");
        }
        return 0;
}

This compiles, however what if we want to turn the version statement around?
I first expected version (!Test) to work, but it doesn't since the grammar says:

VersionCondition:
    version ( Identifier )
    version ( unittest )
    version ( assert )

We are using the first way, the one with the Identifier.
The reason inverting works with if-statements is because they take an "Expression".

I see the way why it doesn't work, but I think it should. Considering that
version (Test) {} else {
works without any issue but looks very ugly.

Can somebody explain if this is an intended decision or what I should do instead of using my ugly replacement?

It depends what do you want to achieve, if you just want a bool at the top of your module to toggle features, then you can do this:

import std.stdio;

enum Test = true;

int main() {
    static if (Test == false) {
        writeln("this will never be called, it won't be compiled");
    } else {
        writeln("hello!");
    }
    return 0;
}

static if is evaluated at compile time, you can mix it with version if you need to provide the flag during compilation

import std.stdio;

version (Test)
    enum HasTest = true;
else
    enum HasTest = false;

int main() {
    static if (HasTest == false) {
        writeln("this will never be called, it won't be compiled");
    } else {
        writeln("hello!");
    }
    return 0;
}

I wish we could use version as expression, to void the repetition:

import std.stdio;

enum HasTest = version (Test) ? true : false;

int main() {
    static if (HasTest == false) {
        writeln("this will never be called, it won't be compiled");
    } else {
        writeln("hello!");
    }
    return 0;
}

If someone able to do it, would be cool to see a PR

December 02

On Saturday, 2 December 2023 at 15:03:25 UTC, ryuukk_ wrote:

>

I wish we could use version as expression, to void the repetition:

import std.stdio;

enum HasTest = version (Test) ? true : false;

Tomek Sowiński wrote this template:

enum bool isVersion(string ver) = !is(typeof({
          mixin("version(" ~ ver ~ ") static assert(0);");
    }));

static assert(isVersion!"assert");
static assert(!isVersion!"Broken");
December 02

On Saturday, 2 December 2023 at 15:48:02 UTC, Nick Treleaven wrote:

>

On Saturday, 2 December 2023 at 15:03:25 UTC, ryuukk_ wrote:

>

I wish we could use version as expression, to void the repetition:

import std.stdio;

enum HasTest = version (Test) ? true : false;

Tomek Sowiński wrote this template:

enum bool isVersion(string ver) = !is(typeof({
          mixin("version(" ~ ver ~ ") static assert(0);");
    }));

static assert(isVersion!"assert");
static assert(!isVersion!"Broken");

I have something similar that i found somewhere here


struct Version
{
    static bool opDispatch(string identifier)()
    {
        mixin("
            version(", identifier, ")
                return true;
            else
                return false;
        ");
    }
}


static if (Version.something == false)
{}

But i don't even use it since it requires me to import a module, it not worth it, i'd rather have version as expression