Re: Inversion of conditional compilation statements
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
Re: Inversion of conditional compilation statements
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"); ```
Re: Inversion of conditional compilation statements
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
Re: Inversion of conditional compilation statements
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.
Inversion of conditional compilation statements
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?
Re: Conditional compilation: Which version identifier for release code ? version(assert) ?
On Thursday, 5 August 2021 at 11:54:38 UTC, Mike Parker wrote: On Thursday, 5 August 2021 at 10:43:01 UTC, wjoe wrote: Could you elaborate on ```version(assert)``` a bit more, please ? Like I compiled with ```-release, -g``` and without the 2 options but the ```assert``` branch was always taken. Could it be that ```-unittest``` has something to do with it ? Yes, -unittest overrides -release and enables asserts. -check=assert=off overrides both. It is sort of embarassing reading this after one night's sleep. But the lesson learned was well worth it, thanks :) So in light of all of this what I was looking for is ```D_NoBoundsChecks``` which you mentioned initially.
Re: Conditional compilation: Which version identifier for release code ? version(assert) ?
On Thursday, 5 August 2021 at 11:01:56 UTC, Adam D Ruppe wrote: On Thursday, 5 August 2021 at 09:18:08 UTC, wjoe wrote: If it's to be determined whether or not the code is being compiled in debug or release mode, i.e. e.g. the dmd ```-release``` You should never use the -release flag. It should be renamed to "-enable-security-holes" since that's what it actually does. This is good advice. Actually I had no intention to *use* the ```-release``` option. My question was aimed at getting an understanding of the different version identifiers and how they are affected by the command line options in order to be able to pick one that reflects the users expectations. My wording should have been better. Sorry for the confusion. Instead you can disable specific things as-needed, but it is probably never needed. These are also never supposed to actually change the behavior of your program, but in reality, like I said they do tend to change it - by enabling security holes. However isn't the point of using version identifiers and these options to actually change the behavior of the program ? I mean if bounds checking is enabled I expect the program to behave differently, i.e. to abort if something is out of bounds.
Re: Conditional compilation: Which version identifier for release code ? version(assert) ?
On Thursday, 5 August 2021 at 10:43:01 UTC, wjoe wrote: Could you elaborate on ```version(assert)``` a bit more, please ? Like I compiled with ```-release, -g``` and without the 2 options but the ```assert``` branch was always taken. Could it be that ```-unittest``` has something to do with it ? Yes, -unittest overrides -release and enables asserts. -check=assert=off overrides both. I agree with Adam about avoiding -release. -debug is useful. -release, not so much since we have finer control over enabling/disabling checks these days.
Re: Conditional compilation: Which version identifier for release code ? version(assert) ?
On Thursday, 5 August 2021 at 09:18:08 UTC, wjoe wrote: If it's to be determined whether or not the code is being compiled in debug or release mode, i.e. e.g. the dmd ```-release``` You should never use the -release flag. It should be renamed to "-enable-security-holes" since that's what it actually does. Instead you can disable specific things as-needed, but it is probably never needed. These are also never supposed to actually change the behavior of your program, but in reality, like I said they do tend to change it - by enabling security holes.
Re: Conditional compilation: Which version identifier for release code ? version(assert) ?
On Thursday, 5 August 2021 at 10:08:12 UTC, Mike Parker wrote: On Thursday, 5 August 2021 at 09:18:08 UTC, wjoe wrote: Given that we have `version(assert)` and `version(D_NoBoundsChecks)`, it probably makes sense to also have equivalents to test if contracts are enabled, or if bounds checking is enabled only in safe code. Then you'd be able to cover all the bases that -release does. Sounds like a candidate for an enhancement request. Thanks, that helps a lot. I agree about release and debug modes. It got stuck in my mind when I used Visual Studio years ago which, at least at the time, created a Debug and Release configuration by default. Could you elaborate on ```version(assert)``` a bit more, please ? Like I compiled with ```-release, -g``` and without the 2 options but the ```assert``` branch was always taken. Could it be that ```-unittest``` has something to do with it ?
Re: Conditional compilation: Which version identifier for release code ? version(assert) ?
On Thursday, 5 August 2021 at 09:18:08 UTC, wjoe wrote: If it's to be determined whether or not the code is being compiled in debug or release mode, i.e. e.g. the dmd ```-release``` or ```-g``` options, which version identifier is supposed to be used ? There's no ```release``` identifier and ```-debug``` switch and ```debug()``` condition are something else. There's ```assert - Checks are being emitted for AssertExpressions```. With the exception for ```assert(0)```, those checks are omitted in release mode so this could be used for that purpose, right? I don't think it would make much sense to have a `version(release)`, as there's really no such thing as a "release mode", or a "debug mode" either. -release is just a shorthand to disable certain features that you can also disable individually, and -debug means whatever you want it to mean. Given that we have `version(assert)` and `version(D_NoBoundsChecks)`, it probably makes sense to also have equivalents to test if contracts are enabled, or if bounds checking is enabled only in safe code. Then you'd be able to cover all the bases that -release does. Sounds like a candidate for an enhancement request.
Conditional compilation: Which version identifier for release code ? version(assert) ?
If it's to be determined whether or not the code is being compiled in debug or release mode, i.e. e.g. the dmd ```-release``` or ```-g``` options, which version identifier is supposed to be used ? There's no ```release``` identifier and ```-debug``` switch and ```debug()``` condition are something else. There's ```assert - Checks are being emitted for AssertExpressions```. With the exception for ```assert(0)```, those checks are omitted in release mode so this could be used for that purpose, right?
Re: What is the equivalent of -version=Flag for conditional compilation in the ldc2 compiler?
On Friday, 5 June 2020 at 22:36:23 UTC, data pulverizer wrote: Hi, I was switching from dmd to ldc2 and would like to know the equivalent command line for conditional compilation -version=Flag I was using in dmd. I checked the ldc2 --help but didn't see anything relevant. Version there refers to compiler version or some other unrelated things. You can also use `ldmd2` as driver for ldc2 with dmd commandline syntax. -Johan
Re: What is the equivalent of -version=Flag for conditional compilation in the ldc2 compiler?
On Friday, 5 June 2020 at 22:39:23 UTC, Steven Schveighoffer wrote: It's in there, I had to do grep to find it: --d-version= - Compile in version code >= or identified by -Steve Thanks, I tried that but didn't realise I still had the old version flag in the command line and assumed it didn't work! Lol - silly!
Re: What is the equivalent of -version=Flag for conditional compilation in the ldc2 compiler?
On 6/5/20 6:36 PM, data pulverizer wrote: Hi, I was switching from dmd to ldc2 and would like to know the equivalent command line for conditional compilation -version=Flag I was using in dmd. I checked the ldc2 --help but didn't see anything relevant. Version there refers to compiler version or some other unrelated things. It's in there, I had to do grep to find it: --d-version= - Compile in version code >= or identified by -Steve
What is the equivalent of -version=Flag for conditional compilation in the ldc2 compiler?
Hi, I was switching from dmd to ldc2 and would like to know the equivalent command line for conditional compilation -version=Flag I was using in dmd. I checked the ldc2 --help but didn't see anything relevant. Version there refers to compiler version or some other unrelated things. Thanks
Re: OR in version conditional compilation
On Saturday, 21 March 2020 at 00:12:20 UTC, Jonathan M Davis wrote: 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. None of that is limited specifically to ifdefs. If you modify code not in an ifdef you can still cause bugs that only materialize on specific platforms. This is the nature of building for multiple platforms at the low level, hell you'll still have problems even in Java. The D test suite doesn't run unit tests for every platform for all libraries. There's also debug assert statements that fail, and at least last I checked for some platforms didn't run debug builds, so the tests don't catch this. And not everyone develops for those platforms so I guess no one does a debug build on their systems either. 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 Like I said in my other comment. This only works if you can assert out of it, and in C and C++ it is the same. There's a bigger problem that still isnt solved, if you need one version statement that doesn't assert to failure. Since a typo will just evaluate to false, the version statement may never be active under any circumstance and it would be difficult to fins such a bug. For example for conguration options, there's no other versions you would put in else versions, and it isnt intended to fail if that configuration version isnt there. The version feature inherited one of C's worst characteristics of the preprocessor for ifdef.
Re: OR in version conditional compilation
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
Re: OR in version conditional compilation
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? In general, I think that Walter's approach here is probably the right one, but it can certainly be annoying in cases where you have to duplicate code that actually is the same rather than being subtly different, and a lot of people dislike it enough that they use workarounds like those discussed in this thread. Sadly it still shares probably the worst bug with the C preposser in that anything that isnt defined simply evaluates to false. If you have a typo then the code will still "work". His approach only works if you can put an assert in the else branch. Which is the case for C/C++ as well. That isnt always possible, as a result you still have the same problem with typos. And of course, some of the same bugs that come up with #ifdefs come up with static ifs in generic code (particularly with range-based code that changes what it's doing based on arange's type), but at least those can be found with thorough tests on a single platform, whereas version-related bugs tend to require that you run thorough tests on each platform. - Jonathan M Davis You still need to test your code on those platforms, so if you are supporting them you still have related problems.
Re: OR in version conditional compilation
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. In general, I think that Walter's approach here is probably the right one, but it can certainly be annoying in cases where you have to duplicate code that actually is the same rather than being subtly different, and a lot of people dislike it enough that they use workarounds like those discussed in this thread. And of course, some of the same bugs that come up with #ifdefs come up with static ifs in generic code (particularly with range-based code that changes what it's doing based on arange's type), but at least those can be found with thorough tests on a single platform, whereas version-related bugs tend to require that you run thorough tests on each platform. - Jonathan M Davis
Re: OR in version conditional compilation
https://issues.dlang.org/show_bug.cgi?id=19495#c1
Re: OR in version conditional compilation
On Wednesday, 18 March 2020 at 16:23:26 UTC, IGotD- wrote: 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? The usual workaround is to define a common version, e.g. version(X86) version = X86_ANY version(X86_64) version = X86_ANY version(X86_ANY) { // your code here }
Re: OR in version conditional compilation
On 3/18/20 12:23 PM, IGotD- 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? No, it's not possible. And it won't ever be possible, Walter is dead-set against it. If you want to know the history, look wy back in the forums. This question comes up every so often. There is a workaround though: template v(string versionID) { mixin("version(" ~ versionID ~ ") enum v = true; else enum v = false;"); } static if(v!"X86_64" || v!"X86") ... -Steve
OR in version conditional compilation
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?
Re: Conditional compilation of array of structs initializer
Thanks Mike!
Re: Conditional compilation of array of structs initializer
On Friday, 10 November 2017 at 06:22:51 UTC, Tony wrote: Doing a port of some C code that has an #ifdef in the middle of an initialization for an array of structs. I am getting a compile error trying to get equivalent behavior with "static if" or "version". Is there a way to achieve this other than making two separate array initialization sections? struct a { int y; int z; } immutable string situation = "abc"; int main() { a[] theArray = [ { 10, 20 }, // version(abc) static if (situation == "abc") { { 30, 40 }, } { 50, 60 } ]; return 0; } Here's my attempt. There's probably a more elegant way, but it's the best I could do. import std.stdio; struct a { int y; int z; } enum situation = "abc"; int main() { enum head = "a[] theArray = [ {10, 20},"; static if (situation == "abc") { enum middle = "{ 30, 40},"; } else { enum middle = ""; } enum tail = "{ 50, 60 }];"; mixin(head ~ middle ~ tail); writeln(head ~ middle ~ tail); return 0; } The use of enums for this is called manifest constants (https://dlang.org/spec/enum.html#manifest_constants). It's more analogous to #define in C. Mixins are documented here (https://dlang.org/spec/statement.html#mixin-statement) Mike
Conditional compilation of array of structs initializer
Doing a port of some C code that has an #ifdef in the middle of an initialization for an array of structs. I am getting a compile error trying to get equivalent behavior with "static if" or "version". Is there a way to achieve this other than making two separate array initialization sections? struct a { int y; int z; } immutable string situation = "abc"; int main() { a[] theArray = [ { 10, 20 }, // version(abc) static if (situation == "abc") { { 30, 40 }, } { 50, 60 } ]; return 0; }
Re: Conditional Compilation Multiple Versions
Druntime uses this for its translation of POSIX header files: https://github.com/dlang/druntime/blob/master/src/core/sys/posix/config.d An example: https://github.com/dlang/druntime/blob/master/src/core/sys/posix/sys/resource.d#L96 Ok, I see. Thanks! (I've gotta try reggae someday) :)
Re: Conditional Compilation Multiple Versions
On Friday, 6 January 2017 at 13:44:37 UTC, Claude wrote: Yes, it works quite well for most use cases and should generally be preferred. I disagree that it scales, though. At some point (a point that is highly project-dependent), it breaks down, requiring either very large modules or duplicated versions across multiple modules. Yes, in that case, you would probably break it down into several specialized config modules. I meant it forces you not to put directly version(Windows) into your code, but rather version(ThatFeatureSupportedByWindowsAmongstOtherOSs). Yes, this is the idiom that version() encourages. You can put all your configuration logic in one place in your build script and then pass -version=hasFeature to your build. If you use reggae, you can even write your configuration logic in D: https://github.com/atilaneves/reggae/ My position is that I will always choose version blocks first, but if I find myself in a situation where I have to choose between duplicating version statements (e.g. version(A) {version=AorB; version=AorC;}) across multiple modules and restructuring my code to accommodate versioning, I much prefer to use the enum alternative as an escape hatch. Ok, that's interesting. Do you have code samples where you do that? I'm just curious. Druntime uses this for its translation of POSIX header files: https://github.com/dlang/druntime/blob/master/src/core/sys/posix/config.d An example: https://github.com/dlang/druntime/blob/master/src/core/sys/posix/sys/resource.d#L96
Re: Conditional Compilation Multiple Versions
On Friday, 6 January 2017 at 13:27:06 UTC, Mike Parker wrote: version(Windows) enum bool WindowsSupported = true; else enum bool WindowsSupported = false; Well, yes, that was a bad example. I thought to change it before sending my post but I could find any other meaningful alternative. My point was, that you can re-define WindowsSupported as a version even if it already defined, but not as an enum. And sometimes, you cannot simply use the else statement without creating another indented block (which seems a bit awkward). Yes, it works quite well for most use cases and should generally be preferred. I disagree that it scales, though. At some point (a point that is highly project-dependent), it breaks down, requiring either very large modules or duplicated versions across multiple modules. Yes, in that case, you would probably break it down into several specialized config modules. I meant it forces you not to put directly version(Windows) into your code, but rather version(ThatFeatureSupportedByWindowsAmongstOtherOSs). My position is that I will always choose version blocks first, but if I find myself in a situation where I have to choose between duplicating version statements (e.g. version(A) {version=AorB; version=AorC;}) across multiple modules and restructuring my code to accommodate versioning, I much prefer to use the enum alternative as an escape hatch. Ok, that's interesting. Do you have code samples where you do that? I'm just curious.
Re: Conditional Compilation Multiple Versions
Glad hear it's working for you! On Friday, 6 January 2017 at 10:25:26 UTC, Claude wrote: 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 These can be condensed to: version(Win32) enum bool WindowsSupported = true; else version(Win64) enum bool WindowsSupported = true; else enum bool WindowsSupported = false; Or even better, since it doesn't appear you need to distinguish between 32-bit & 64-bit: version(Windows) enum bool WindowsSupported = true; else enum bool WindowsSupported = false; 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. For me, the readability is no issue. I would put that block above in a single module (which I like to call config.d) and then import it where I need it. This actually is a lot cleaner for the corner cases where version breaks down (see below). 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... version(Windows) { } 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. Yes, it works quite well for most use cases and should generally be preferred. I disagree that it scales, though. At some point (a point that is highly project-dependent), it breaks down, requiring either very large modules or duplicated versions across multiple modules. My position is that I will always choose version blocks first, but if I find myself in a situation where I have to choose between duplicating version statements (e.g. version(A) {version=AorB; version=AorC;}) across multiple modules and restructuring my code to accommodate versioning, I much prefer to use the enum alternative as an escape hatch.
Re: Conditional Compilation Multiple Versions
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!
Re: Conditional Compilation Multiple Versions
On Saturday, 13 June 2015 at 12:21:50 UTC, ketmar wrote: On Fri, 12 Jun 2015 20:41:59 -0400, bitwise wrote: Is there a way to compile for multiple conditions? Tried all these: version(One | Two){ } version(One || Two){ } version(One && Two){ } version(One) | version(Two){ } version(One) || version(Two){ } version(One) && version(Two){ } Bit nope. Walter is against that, so we'll not have it, despite the triviality of the patch. I'm digging up that thread, as I want to do some multiple conditional compilation a well. I have a couple of questions: * Why is Walter against that? There must be some good reasons. * 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)? Here' the kind of stuff I'd like to translate from C: #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #define YEP_MICROSOFT_COMPILER #elif defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__CUDA_ARCH__) #define YEP_GNU_COMPILER #elif defined(__INTEL_COMPILER) ... #if defined(_M_IX86) || defined(i386) || defined(__i386) || defined(__i386__) || defined(_X86_) || defined(__X86__) || defined(__I86__) || defined(__INTEL__) || defined(__THW_INTEL__) #define YEP_X86_CPU #define YEP_X86_ABI #elif defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) ...
Re: Conditional compilation inside an array initializer
On 01/18/2016 04:38 PM, Adam D. Ruppe wrote: On Tuesday, 19 January 2016 at 00:33:21 UTC, Johan Engelen wrote: Is it possible to do conditional compilation inside an array initializer? No, but you might break it up: enum inttable_1 = [1,4]; version(smth) enum inttable_middle = [5,6]; else enum inttable_middle = []; enum inttable_2 = [8, 1345]; int[] inttable = inttable_1 ~ inttable_middle ~ inttable_2; I was writing something similar: int[] table; // Alternatively, consider 'shared static this()' static this() { const tens = [ 10, 20 ]; const hundreds = [ 100, 200 ]; const thousands = [ 1000, 2000 ]; table ~= tens; version (smth) { table ~= hundreds; } table ~= thousands; } version = smth; void main() { import std.stdio; writeln(table); } Ali
Re: Conditional compilation inside an array initializer
On Tuesday, 19 January 2016 at 00:33:21 UTC, Johan Engelen wrote: Is it possible to do conditional compilation inside an array initializer? No, but you might break it up: enum inttable_1 = [1,4]; version(smth) enum inttable_middle = [5,6]; else enum inttable_middle = []; enum inttable_2 = [8, 1345]; int[] inttable = inttable_1 ~ inttable_middle ~ inttable_2;
Conditional compilation inside an array initializer
Is it possible to do conditional compilation inside an array initializer? Something like this: int[] inttable = [ 1, 4, version(smth) { // <--- does not compile 5, 6, } 8, 1345 ]; (real world case: https://github.com/ldc-developers/ldc/blob/merge-2.069/ddmd/idgen.d#L279) If it is not possible, what alternative solution would you use? Thanks!
Re: Conditional Compilation Multiple Versions
On Sat, 13 Jun 2015 12:20:40 -0400, ketmar wrote: On Sat, 13 Jun 2015 13:49:49 +, anonymous wrote: Taking it one step further: template Version(string name) { mixin(" version("~name~") enum Version = true; else enum Version = false; "); } static if(Version!"One" || Version!"Two") { ... } very elegant. Elegant indeed, but I think my pull request would be frowned upon if I tried to use this in druntime. Bit
Re: Conditional Compilation Multiple Versions
On Sat, 13 Jun 2015 13:49:49 +, anonymous wrote: > Taking it one step further: > > template Version(string name) > { > mixin(" > version("~name~") enum Version = true; > else enum Version = false; > "); > } > > static if(Version!"One" || Version!"Two") > { > ... > } very elegant. signature.asc Description: PGP signature
Re: Conditional Compilation Multiple Versions
On Sat, 13 Jun 2015 12:01:29 -0400, bitwise wrote: >> nope. Walter is against that, so we'll not have it, despite the >> triviality of the patch. > > Any idea what the rationale was for not allowing it? i don't remember. that murmuring about "it makes the code harder to read" goes beyond me, so it's hard to remember. signature.asc Description: PGP signature
Re: Conditional Compilation Multiple Versions
On Sat, 13 Jun 2015 08:21:50 -0400, ketmar wrote: On Fri, 12 Jun 2015 20:41:59 -0400, bitwise wrote: Is there a way to compile for multiple conditions? Tried all these: version(One | Two){ } version(One || Two){ } version(One && Two){ } version(One) | version(Two){ } version(One) || version(Two){ } version(One) && version(Two){ } Bit nope. Walter is against that, so we'll not have it, despite the triviality of the patch. Any idea what the rationale was for not allowing it? Bit
Re: Conditional Compilation Multiple Versions
On Saturday, 13 June 2015 at 00:47:37 UTC, Mike Parker wrote: // config.d version(One) enum One = true; else enum One = false; version(Two) enum Two = true; else enum Two = false; // other.d import config; static if(One || Two) { ... } Taking it one step further: template Version(string name) { mixin(" version("~name~") enum Version = true; else enum Version = false; "); } static if(Version!"One" || Version!"Two") { ... }
Re: Conditional Compilation Multiple Versions
On Fri, 12 Jun 2015 20:41:59 -0400, bitwise wrote: > Is there a way to compile for multiple conditions? > > Tried all these: > > version(One | Two){ } > version(One || Two){ } > version(One && Two){ } > version(One) | version(Two){ } > version(One) || version(Two){ } > version(One) && version(Two){ } > >Bit nope. Walter is against that, so we'll not have it, despite the triviality of the patch. signature.asc Description: PGP signature
Re: Conditional Compilation Multiple Versions
On Fri, 12 Jun 2015 20:55:51 -0400, Márcio Martins wrote: I know... I too hate that one can't use simple logic ops... Indeed... Thanks. Bit
Re: Conditional Compilation Multiple Versions
On Saturday, 13 June 2015 at 00:42:00 UTC, bitwise wrote: Is there a way to compile for multiple conditions? version(One) version = OneOrTwo; else version(Two) version = OneOrTwo; version(OneOrTwo) { writeln("moo"); } --- version(One) version(Two) version = OneAndTwo; version(OneAndTwo) { writeln("moo moo"); } I know... I too hate that one can't use simple logic ops...
Re: Conditional Compilation Multiple Versions
On 6/13/2015 9:41 AM, bitwise wrote: Is there a way to compile for multiple conditions? Tried all these: version(One | Two){ } version(One || Two){ } version(One && Two){ } version(One) | version(Two){ } version(One) || version(Two){ } version(One) && version(Two){ } Bit // config.d version(One) enum One = true; else enum One = false; version(Two) enum Two = true; else enum Two = false; // other.d import config; static if(One || Two) { ... }
Conditional Compilation Multiple Versions
Is there a way to compile for multiple conditions? Tried all these: version(One | Two){ } version(One || Two){ } version(One && Two){ } version(One) | version(Two){ } version(One) || version(Two){ } version(One) && version(Two){ } Bit
Re: Conditional compilation for debug/release
On Monday, 6 April 2015 at 15:24:53 UTC, Namespace wrote: On Monday, 6 April 2015 at 15:15:48 UTC, Johan Engelen wrote: On Monday, 6 April 2015 at 14:55:58 UTC, Namespace wrote: debug { pragma(lib, "libcmtd.lib"); } else { pragma(lib, "libcmt.lib"); } Thanks for the quick reply! Worth adding an example like that to http://dlang.org/version.html ? It's there already: http://dlang.org/version.html#debug ;) It was not obvious to me that "else" would work. But reading the whole page again (not just the "debug" part), I see that indeed the info is already there.
Re: Conditional compilation for debug/release
On Monday, 6 April 2015 at 15:15:48 UTC, Johan Engelen wrote: On Monday, 6 April 2015 at 14:55:58 UTC, Namespace wrote: debug { pragma(lib, "libcmtd.lib"); } else { pragma(lib, "libcmt.lib"); } Thanks for the quick reply! Worth adding an example like that to http://dlang.org/version.html ? It's there already: http://dlang.org/version.html#debug ;)
Re: Conditional compilation for debug/release
On Monday, 6 April 2015 at 14:55:58 UTC, Namespace wrote: debug { pragma(lib, "libcmtd.lib"); } else { pragma(lib, "libcmt.lib"); } Thanks for the quick reply! Worth adding an example like that to http://dlang.org/version.html ?
Re: Conditional compilation for debug/release
On Monday, 6 April 2015 at 14:50:29 UTC, Johan Engelen wrote: How do conditionally compile code for either release ("-release") or debug ("-debug")? Something like this: version(Debug) { pragma(lib, "libcmtd.lib"); } else { pragma(lib, "libcmt.lib"); } In the documentation [1], I don't see any predefined version identifiers for this purpose. Thanks, Johan [1] http://dlang.org/version.html debug { pragma(lib, "libcmtd.lib"); } else { pragma(lib, "libcmt.lib"); }
Conditional compilation for debug/release
How do conditionally compile code for either release ("-release") or debug ("-debug")? Something like this: version(Debug) { pragma(lib, "libcmtd.lib"); } else { pragma(lib, "libcmt.lib"); } In the documentation [1], I don't see any predefined version identifiers for this purpose. Thanks, Johan [1] http://dlang.org/version.html
Re: Conditional Compilation for Specific Windows
On 2015-01-07 20:48, Jonathan Marler wrote: I've looked up the windows version helper functions (http://msdn.microsoft.com/en-us/library/windows/desktop/dn424972(v=vs.85).aspx). The problem is that these functions are not defined in DMD's user32.lib. I could use the operating system's user32.lib but it is in COFF format, so I would have to convert my D object files to COFF and then compile using MSVC or GNU GCC for windows (or I could try converting the OS user32.lib to OMF). Or, I could add the functions to DMD's user32.lib but as far as I know this is a private binary managed by Digital Mars that I can't contribute to? Am I wrong? Does anyone else have a solution or an idea on this? Note: I've wanted to use other windows function in the past that were missing from DMD's user32.lib file. A solution to solve this for multiple functions would be ideal, thanks. You can either: 1. Convert an up to date user32.lib to OMF 2. Create your own user32.lib from the DLL 3. Compile using the COFF format and use the Visual Studio runtime instead. This has been recently added (I'm not sure if it's released yet) and requires using a flag -- /Jacob Carlborg
Re: Conditional Compilation for Specific Windows
On Wednesday, 7 January 2015 at 19:48:16 UTC, Jonathan Marler wrote: On Wednesday, 7 January 2015 at 18:50:40 UTC, Jacob Carlborg wrote: On 2015-01-07 19:27, Jonathan Marler wrote: I'm looking at the Windows multicast API. It has different socket options depending on if you are on Windows XP or Windows Vista (and later). Is there a way to tell at runtime which version of windows you are on? Note: I'm specifically talking about runtime because I want the same binary to run on all windows versions so I have to support both and determine which one I am running on at runtime. Use the regular system API's as you would in C. Should be easy to find if you search the web. I've looked up the windows version helper functions (http://msdn.microsoft.com/en-us/library/windows/desktop/dn424972(v=vs.85).aspx). The problem is that these functions are not defined in DMD's user32.lib. I could use the operating system's user32.lib but it is in COFF format, so I would have to convert my D object files to COFF and then compile using MSVC or GNU GCC for windows (or I could try converting the OS user32.lib to OMF). Or, I could add the functions to DMD's user32.lib but as far as I know this is a private binary managed by Digital Mars that I can't contribute to? Am I wrong? Does anyone else have a solution or an idea on this? Note: I've wanted to use other windows function in the past that were missing from DMD's user32.lib file. A solution to solve this for multiple functions would be ideal, thanks. You could bypass user32.lib by using directly user32.dll via LoadLibrary()/GetProcAddress(). -- Paulo
Re: Conditional Compilation for Specific Windows
On Wednesday, 7 January 2015 at 18:50:40 UTC, Jacob Carlborg wrote: On 2015-01-07 19:27, Jonathan Marler wrote: I'm looking at the Windows multicast API. It has different socket options depending on if you are on Windows XP or Windows Vista (and later). Is there a way to tell at runtime which version of windows you are on? Note: I'm specifically talking about runtime because I want the same binary to run on all windows versions so I have to support both and determine which one I am running on at runtime. Use the regular system API's as you would in C. Should be easy to find if you search the web. I've looked up the windows version helper functions (http://msdn.microsoft.com/en-us/library/windows/desktop/dn424972(v=vs.85).aspx). The problem is that these functions are not defined in DMD's user32.lib. I could use the operating system's user32.lib but it is in COFF format, so I would have to convert my D object files to COFF and then compile using MSVC or GNU GCC for windows (or I could try converting the OS user32.lib to OMF). Or, I could add the functions to DMD's user32.lib but as far as I know this is a private binary managed by Digital Mars that I can't contribute to? Am I wrong? Does anyone else have a solution or an idea on this? Note: I've wanted to use other windows function in the past that were missing from DMD's user32.lib file. A solution to solve this for multiple functions would be ideal, thanks.
Re: Conditional Compilation for Specific Windows
On Wednesday, 7 January 2015 at 18:50:40 UTC, Jacob Carlborg wrote: On 2015-01-07 19:27, Jonathan Marler wrote: I'm looking at the Windows multicast API. It has different socket options depending on if you are on Windows XP or Windows Vista (and later). Is there a way to tell at runtime which version of windows you are on? Note: I'm specifically talking about runtime because I want the same binary to run on all windows versions so I have to support both and determine which one I am running on at runtime. Use the regular system API's as you would in C. Should be easy to find if you search the web. Oh wait a second, I misunderstood you. You were talking about using the regular Windows APIs to determine which version of windows I am running on. I was going to do that but I wanted to check if D has created a wrapping for that or uses a particular convention.
Re: Conditional Compilation for Specific Windows
On Wednesday, 7 January 2015 at 18:50:40 UTC, Jacob Carlborg wrote: On 2015-01-07 19:27, Jonathan Marler wrote: I'm looking at the Windows multicast API. It has different socket options depending on if you are on Windows XP or Windows Vista (and later). Is there a way to tell at runtime which version of windows you are on? Note: I'm specifically talking about runtime because I want the same binary to run on all windows versions so I have to support both and determine which one I am running on at runtime. Use the regular system API's as you would in C. Should be easy to find if you search the web. They are the regular system APIs. They change depending on which version of windows you are on (http://msdn.microsoft.com/en-us/library/windows/desktop/ms738558(v=vs.85).aspx). Again, how do I determine which version of windows I am on? My code will default to using the new API (because it is the most efficient), but then will fall back to using the old API if it can detect that the current version of Windows does not support the new API.
Re: Conditional Compilation for Specific Windows
On 2015-01-07 19:27, Jonathan Marler wrote: I'm looking at the Windows multicast API. It has different socket options depending on if you are on Windows XP or Windows Vista (and later). Is there a way to tell at runtime which version of windows you are on? Note: I'm specifically talking about runtime because I want the same binary to run on all windows versions so I have to support both and determine which one I am running on at runtime. Use the regular system API's as you would in C. Should be easy to find if you search the web. -- /Jacob Carlborg
Conditional Compilation for Specific Windows
I'm looking at the Windows multicast API. It has different socket options depending on if you are on Windows XP or Windows Vista (and later). Is there a way to tell at runtime which version of windows you are on? Note: I'm specifically talking about runtime because I want the same binary to run on all windows versions so I have to support both and determine which one I am running on at runtime.
Re: DMD Compiler Version Dependent Conditional Compilation
Thx
Re: DMD Compiler Version Dependent Conditional Compilation
On Monday, 9 June 2014 at 17:36:10 UTC, Nordlöw wrote: Can I use the version keyword or static if to perform conditional compilation that depends on the version of DMD? The __VERSION__ magic token should do the job. David
DMD Compiler Version Dependent Conditional Compilation
Can I use the version keyword or static if to perform conditional compilation that depends on the version of DMD? I typicall something like version(>= DMD_2.0.66) { // use new byChar, byWchar, byDchar, byCodepoint } else { // use old style slower version } If so how?
Re: Conditional compilation
There is the aforementioned extern(system), which is probably your best bet. But I'm wondering if your design could seperate the connection to IUnknown for non-Windows builds? Something like this: version(Windows) interface _Inter_ : IUnknown {} else interface _Inter_ {} // later interface InterfaceA : _Inter_ { //... }
Re: Conditional compilation
On Friday, 7 June 2013 at 12:20:23 UTC, finalpatch wrote: string mixins and template mixins don't work either. On Friday, 7 June 2013 at 12:14:45 UTC, finalpatch wrote: Hi folks, I need to apply different calling conventions to the same interfaces when compiling for different platform. It's something like this: OSX: interface InterfaceA : IUnknown { extern(C): ... } Windows: interface InterfaceA : IUnknown { ... } I have to add extern(C) on OSX because apparently when the compiler sees IUnknown it automatically assumes the calling convention is extern(Windows) and in order to maintain compatibility with existing system I have to explicitly declare them as extern(C). Now I have several dozens of interfaces like the above. I don't want to repeat them for OSX and Windows because the interface definitions are identical except the extern(C) line. I have tried using version() like this: interface InterfaceA : IUnknown { version(OSX) { extern(C): } ...methohds. } but it doesn't work because version limits the scope of the extern(C). static if has the same problem. In C/C++ this is really easy, I can simply define a macro which expands to extern(C) on OSX and nothing on windows. Is there any way to achieve this in D without repeating the interface definitions? string mixin will work import std.stdio; enum :string { //define relevant functions in this string x1 = `void testfunc(string str) { writeln(str); }` } version(X) { extern(C) mixin(x1); string str2 = "c version"; } version(Y) { extern(Windows) mixin(x1); string str2 = "windows version"; } void main() { testfunc(str2); } Yes it's ... well ... not very ... umm But it works :) extern(system) MIGHT be a better option.
Re: Conditional compilation
On Friday, 7 June 2013 at 12:14:45 UTC, finalpatch wrote: Hi folks, I need to apply different calling conventions to the same interfaces when compiling for different platform. extern(System) On Windows, it will be seen by the compiler as extern(Windows), elsewhere as extern(C).
Re: Conditional compilation
string mixins and template mixins don't work either. On Friday, 7 June 2013 at 12:14:45 UTC, finalpatch wrote: Hi folks, I need to apply different calling conventions to the same interfaces when compiling for different platform. It's something like this: OSX: interface InterfaceA : IUnknown { extern(C): ... } Windows: interface InterfaceA : IUnknown { ... } I have to add extern(C) on OSX because apparently when the compiler sees IUnknown it automatically assumes the calling convention is extern(Windows) and in order to maintain compatibility with existing system I have to explicitly declare them as extern(C). Now I have several dozens of interfaces like the above. I don't want to repeat them for OSX and Windows because the interface definitions are identical except the extern(C) line. I have tried using version() like this: interface InterfaceA : IUnknown { version(OSX) { extern(C): } ...methohds. } but it doesn't work because version limits the scope of the extern(C). static if has the same problem. In C/C++ this is really easy, I can simply define a macro which expands to extern(C) on OSX and nothing on windows. Is there any way to achieve this in D without repeating the interface definitions?
Conditional compilation
Hi folks, I need to apply different calling conventions to the same interfaces when compiling for different platform. It's something like this: OSX: interface InterfaceA : IUnknown { extern(C): ... } Windows: interface InterfaceA : IUnknown { ... } I have to add extern(C) on OSX because apparently when the compiler sees IUnknown it automatically assumes the calling convention is extern(Windows) and in order to maintain compatibility with existing system I have to explicitly declare them as extern(C). Now I have several dozens of interfaces like the above. I don't want to repeat them for OSX and Windows because the interface definitions are identical except the extern(C) line. I have tried using version() like this: interface InterfaceA : IUnknown { version(OSX) { extern(C): } ...methohds. } but it doesn't work because version limits the scope of the extern(C). static if has the same problem. In C/C++ this is really easy, I can simply define a macro which expands to extern(C) on OSX and nothing on windows. Is there any way to achieve this in D without repeating the interface definitions?
Re: Conditional compilation for non-release version
On 28/04/12 15:03, F i L wrote: Or you could use debug statements: Yes, that was what I wanted to avoid -- I wanted the tests to be there by default, not only when debugging ... :-) AFAICS the foreach loop probably does get optimized out by the compiler (I'm using GDC); if anything is left, the time it adds is negligible compared to the natural variation in runtime of the program. In the end I decided to play ultra-safe and add assert() statements in every context where the array entries are used. Those extra checks don't actually add anything to the non-release runtime, so far as I can tell.
Re: Conditional compilation for non-release version
asserts aren't compiled into release builds (except assert(false)). So, if the loop only contains asserts, the compiler *should* be able to strip out the loop altogether. I don't know if DMD actually does that, though. Or you could use debug statements: debug foreach (x; largeArray) { ... } you'll need to compile with "-debug" for the loop to be included.
Re: Conditional compilation for non-release version
On 04/28/2012 02:05 PM, Joseph Rushton Wakeling wrote: Hello all, I've just been reading through this page: http://dlang.org/version.html Is there a way to put in place a conditional segment of code that is included if the code is _not_ compiled with the -release flag? Of course I can put in a debug statement, but that would require me to compile with -debug. I'd like the opposite, that unless I explicitly specify the code as release-ready, the specified set of checks will be performed. The reason I'm asking is because the checks I want to perform are of the form, foreach(x; myVeryLargeArray) { assert(/* ... some condition about x */); } ... and I'm concerned that with the foreach() loop in place, it will slow down the code even if the assert() statements are ignored at compile time. So I'd like to be able to do something instead like, version(!release) { foreach(x; myVeryLargeArray) { assert(/* ... some condition about x */); } } ... is this possible? Thanks & best wishes, -- Joe assert({ /* code you want to execute in non-release mode */ return true; }());
Re: Conditional compilation for non-release version
Joseph Rushton Wakeling: Is there a way to put in place a conditional segment of code that is included if the code is _not_ compiled with the -release flag? Contract programming? D is designed to make it hard on purpose to do what you want to do. The reason I'm asking is because the checks I want to perform are of the form, foreach(x; myVeryLargeArray) { assert(/* ... some condition about x */); } ... and I'm concerned that with the foreach() loop in place, it will slow down the code even if the assert() statements are ignored at compile time. So I'd like to be able to do something instead like, version(!release) { foreach(x; myVeryLargeArray) { assert(/* ... some condition about x */); } } ... is this possible? My suggestion is to use a pure helper predicate, possibly nothrow too (a pure lambda too is OK): bool isGood(MyType x) pure { ... } foreach(x; myVeryLargeArray) { assert(isGood(x)); } The purity of the predicate is almost necessary, to be sure your program behavior doesn't change between release and non-release mode. Bye, bearophile
Conditional compilation for non-release version
Hello all, I've just been reading through this page: http://dlang.org/version.html Is there a way to put in place a conditional segment of code that is included if the code is _not_ compiled with the -release flag? Of course I can put in a debug statement, but that would require me to compile with -debug. I'd like the opposite, that unless I explicitly specify the code as release-ready, the specified set of checks will be performed. The reason I'm asking is because the checks I want to perform are of the form, foreach(x; myVeryLargeArray) { assert(/* ... some condition about x */); } ... and I'm concerned that with the foreach() loop in place, it will slow down the code even if the assert() statements are ignored at compile time. So I'd like to be able to do something instead like, version(!release) { foreach(x; myVeryLargeArray) { assert(/* ... some condition about x */); } } ... is this possible? Thanks & best wishes, -- Joe
Re: Conditional Compilation with Version
O... So I if it is in my main function (which I think it is) I should move it out? That makes sense... Thank you Timon!!
Re: Conditional Compilation with Version
On 09/22/2011 04:17 AM, alex wrote: Hi Y'all!! Just as a note, I am new to the news group, but slightly less new to D =) Back on topic: I am unable to get multiple version specifications to work (from the website) sometihng like: version (foo) { version = bar; version = baz; } version (bar) { ... codes 'n' stuff } version (baz) { ... more codez } every time I get an error which says rhe version statement wants (statement), not '=', unlike from the website article on language is this simply a deprecated feature, or am I doing something wrong? pssst... I use DMD 2.055 on linux x86 (ubuntu, dont be a hater) Probably, the problem is that you try to set versions in function scope. That does not work, version=foo; declarations must be at module scope.
Conditional Compilation with Version
Hi Y'all!! Just as a note, I am new to the news group, but slightly less new to D =) Back on topic: I am unable to get multiple version specifications to work (from the website) sometihng like: version (foo) { version = bar; version = baz; } version (bar) { ... codes 'n' stuff } version (baz) { ... more codez } every time I get an error which says rhe version statement wants (statement), not '=', unlike from the website article on language is this simply a deprecated feature, or am I doing something wrong? pssst... I use DMD 2.055 on linux x86 (ubuntu, dont be a hater)
Semantics of specialization, constraints, and conditional compilation
Mostly babbling... Please comment here and there... :) What are the semantics of the three? What are your guidelines when choosing among them? Is my understanding below correct? Have I missed other related D features? - specialization means "there is a general definition somewhere; but this one is special for the matching conditions in the template parameter list" That is an easy concept, but the syntax can be very confusing. The following example is from the spec at http://digitalmars.com/d/2.0/template.html template TFoo(T : T[]) { ... } (I think we discussed this syntax a short time ago.) The only way that I could wrap my head around that was from right-to-left, and I am still not sure whether this is correct: "If the parameter fits T[] (i.e. if the parameter is an array), then set T to be the type of the array element." Reading it left-to-right doesn't work: "when T matches T[]", which would be impossible, because no type matches the array of that type. - constraints mean "Consider this definition only if the conditions in the constraints are true" This is not that hard either, but there is a problem with constraints. When two definitions of a template given, and when one of them has a constraint, the use that matches the constraints also matches the definition without the constraint: void foo(T)() {} void foo(T)() if (T.sizeof == 4) {} void main() { foo!int(); // <-- compiler error } Error: template instance foo!(int) matches more than one template declaration, foo(T) and foo(T) if (T.sizeof == 4) It means that we must have exclusion on the other template: void foo(T)() if (T.sizeof != 4) // <-- reverse logic {} void foo(T)() if (T.sizeof == 4) // <-- special {} Perhaps this proves that constraints are not suitable for specialization. - conditional programming (static if) means "Include this block of code conditionally" We could use this feature to conditionally include as many lines as we want within the body of the template: void foo(T)() { static if (T.sizeof == 4) { // ... special ... } else { // ... general ... } } The 'is exression' at http://digitalmars.com/d/2.0/expression.html#IsExpression can be very hairy: alias long[char[]] AA; static if (is(AA T : T[U], U : const char[])) { writefln(typeid(T));// long writefln(typeid(U));// const char[] } That is magic! :) Perhaps I should read it from right to left: if U matches const char[] if AA matches T[const char[]] then T is the type of the array element and AA is... ??? brain ache! :) ... trying again ... AA is T... But wait! T was something else Fail! :/ Additionally, there is __traits. The spec at http://digitalmars.com/d/2.0/traits.html says: This is useful for: * Giving better error messages inside generic code than the sometimes hard to follow compiler ones. * Doing a finer grained specialization than template partial specialization allows for. Does it mean "when used with static if?". Thank you, Ali