www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Inversion of conditional compilation statements

reply Johannes Miesenhardt <johannesmiesenhardt gmail.com> writes:
Hello,
I am trying to learn D and I have stumbled upon an issue
Consider this code:
```d
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?
Dec 02 2023
next sibling parent user1234 <user1234 12.de> writes:
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.
Dec 02 2023
prev sibling parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
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:
 ```d
 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: ```D 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 ```D 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: ```D 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
Dec 02 2023
parent reply Nick Treleaven <nick geany.org> writes:
On Saturday, 2 December 2023 at 15:03:25 UTC, ryuukk_ wrote:
 I wish we could use ``version`` as expression, to void the 
 repetition:

 ```D
 import std.stdio;

 enum HasTest = version (Test) ? true : false;
Tomek Sowiński wrote this template: ```d enum bool isVersion(string ver) = !is(typeof({ mixin("version(" ~ ver ~ ") static assert(0);"); })); static assert(isVersion!"assert"); static assert(!isVersion!"Broken"); ```
Dec 02 2023
parent ryuukk_ <ryuukk.dev gmail.com> writes:
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:

 ```D
 import std.stdio;

 enum HasTest = version (Test) ? true : false;
Tomek Sowiński wrote this template: ```d 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 ```D 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
Dec 02 2023