Re: Inversion of conditional compilation statements

2023-12-02 Thread ryuukk_ via Digitalmars-d-learn
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

2023-12-02 Thread Nick Treleaven via Digitalmars-d-learn

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

2023-12-02 Thread ryuukk_ via Digitalmars-d-learn
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

2023-12-02 Thread user1234 via Digitalmars-d-learn
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

2023-12-02 Thread Johannes Miesenhardt via Digitalmars-d-learn

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) ?

2021-08-06 Thread wjoe via Digitalmars-d-learn

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) ?

2021-08-06 Thread wjoe via Digitalmars-d-learn

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) ?

2021-08-05 Thread Mike Parker via Digitalmars-d-learn

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) ?

2021-08-05 Thread Adam D Ruppe via Digitalmars-d-learn

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) ?

2021-08-05 Thread wjoe via Digitalmars-d-learn

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) ?

2021-08-05 Thread Mike Parker via Digitalmars-d-learn

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) ?

2021-08-05 Thread wjoe via Digitalmars-d-learn
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?

2020-06-05 Thread Johan via Digitalmars-d-learn

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?

2020-06-05 Thread data pulverizer via Digitalmars-d-learn
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?

2020-06-05 Thread Steven Schveighoffer via Digitalmars-d-learn

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?

2020-06-05 Thread data pulverizer via Digitalmars-d-learn

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

2020-03-20 Thread jxel via Digitalmars-d-learn
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

2020-03-20 Thread Jonathan M Davis via Digitalmars-d-learn
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

2020-03-20 Thread jxel via Digitalmars-d-learn

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

2020-03-20 Thread Jonathan M Davis via Digitalmars-d-learn
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

2020-03-18 Thread Kagamin via Digitalmars-d-learn

https://issues.dlang.org/show_bug.cgi?id=19495#c1


Re: OR in version conditional compilation

2020-03-18 Thread MoonlightSentinel via Digitalmars-d-learn

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

2020-03-18 Thread Steven Schveighoffer via Digitalmars-d-learn

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

2020-03-18 Thread IGotD- via Digitalmars-d-learn

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

2017-11-09 Thread Tony via Digitalmars-d-learn

Thanks Mike!


Re: Conditional compilation of array of structs initializer

2017-11-09 Thread Michael V. Franklin via Digitalmars-d-learn

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

2017-11-09 Thread Tony via Digitalmars-d-learn
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

2017-01-09 Thread Claude via Digitalmars-d-learn

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

2017-01-07 Thread Joakim via Digitalmars-d-learn

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

2017-01-06 Thread Claude via Digitalmars-d-learn

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

2017-01-06 Thread Mike Parker via Digitalmars-d-learn


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

2017-01-06 Thread Claude via Digitalmars-d-learn

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

2016-10-20 Thread Claude via Digitalmars-d-learn

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

2016-01-18 Thread Ali Çehreli via Digitalmars-d-learn

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

2016-01-18 Thread Adam D. Ruppe via Digitalmars-d-learn

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

2016-01-18 Thread Johan Engelen via Digitalmars-d-learn
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

2015-06-13 Thread bitwise via Digitalmars-d-learn

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

2015-06-13 Thread ketmar via Digitalmars-d-learn
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

2015-06-13 Thread ketmar via Digitalmars-d-learn
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

2015-06-13 Thread bitwise via Digitalmars-d-learn

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

2015-06-13 Thread anonymous via Digitalmars-d-learn

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

2015-06-13 Thread ketmar via Digitalmars-d-learn
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

2015-06-12 Thread bitwise via Digitalmars-d-learn
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

2015-06-12 Thread via Digitalmars-d-learn

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

2015-06-12 Thread Mike Parker via Digitalmars-d-learn

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

2015-06-12 Thread bitwise via Digitalmars-d-learn

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

2015-04-06 Thread Johan Engelen via Digitalmars-d-learn

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

2015-04-06 Thread Namespace via Digitalmars-d-learn

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

2015-04-06 Thread Johan Engelen via Digitalmars-d-learn

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

2015-04-06 Thread Namespace via Digitalmars-d-learn

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

2015-04-06 Thread Johan Engelen via Digitalmars-d-learn
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

2015-01-07 Thread Jacob Carlborg via Digitalmars-d-learn

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

2015-01-07 Thread Paulo Pinto via Digitalmars-d-learn
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

2015-01-07 Thread Jonathan Marler via Digitalmars-d-learn
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

2015-01-07 Thread Jonathan Marler via Digitalmars-d-learn
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

2015-01-07 Thread Jonathan Marler via Digitalmars-d-learn
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

2015-01-07 Thread Jacob Carlborg via Digitalmars-d-learn

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

2015-01-07 Thread Jonathan Marler via Digitalmars-d-learn
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

2014-06-09 Thread Nordlöw

Thx


Re: DMD Compiler Version Dependent Conditional Compilation

2014-06-09 Thread David Nadlinger via Digitalmars-d-learn

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

2014-06-09 Thread Nordlöw
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

2013-06-08 Thread Chris Nicholson-Sauls
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

2013-06-07 Thread Anthony Goins

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

2013-06-07 Thread Mike Parker

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

2013-06-07 Thread finalpatch

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

2013-06-07 Thread finalpatch

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

2012-04-28 Thread Joseph Rushton Wakeling

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

2012-04-28 Thread F i L
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

2012-04-28 Thread Timon Gehr

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

2012-04-28 Thread bearophile

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

2012-04-28 Thread Joseph Rushton Wakeling

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

2011-09-23 Thread alex
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

2011-09-22 Thread Timon Gehr

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

2011-09-21 Thread alex
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

2010-05-20 Thread Ali Çehreli

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