Jump to page: 1 2
Thread overview
Version very simple?
Feb 27, 2011
simendsjo
Feb 27, 2011
David Nadlinger
Feb 27, 2011
simendsjo
Feb 27, 2011
David Nadlinger
Feb 27, 2011
simendsjo
Feb 28, 2011
Jonathan M Davis
Feb 27, 2011
simendsjo
Feb 28, 2011
Trass3r
February 27, 2011
I'm having some problems grokking version.

How would I translate this simple C macro?
#if !defined(IDENT) || !defined(IDENT2)

I've tried the following:
version(!IDENT)
> identifier or integer expected, not !

!version(IDENT)
> Declaration expected, not '!'

version(IDENT || IDENT2)
> found '||' when expecting ')'

version(IDENT) || version(IDENT2)
> Declaration expected, not '||'


This is just plain ugly:
version(IDENT) {
} else {
  version = NOT_IDENT_OR_IDENT2;
}

version(IDENT2) {
} else {
  version = NOT_IDENT_OR_IDENT2;
}

version(NOT_IDENT_OR_IDENT2) {
  // Finally
}
February 27, 2011
On Sun, 27 Feb 2011 09:52:01 -0500, simendsjo <simen.endsjo@pandavre.com> wrote:

> I'm having some problems grokking version.
>
> How would I translate this simple C macro?
> #if !defined(IDENT) || !defined(IDENT2)
>
> I've tried the following:
> version(!IDENT)
>  > identifier or integer expected, not !
>
> !version(IDENT)
>  > Declaration expected, not '!'
>
> version(IDENT || IDENT2)
>  > found '||' when expecting ')'
>
> version(IDENT) || version(IDENT2)
>  > Declaration expected, not '||'
>
>
> This is just plain ugly:
> version(IDENT) {
> } else {
>    version = NOT_IDENT_OR_IDENT2;
> }
>
> version(IDENT2) {
> } else {
>    version = NOT_IDENT_OR_IDENT2;
> }
>
> version(NOT_IDENT_OR_IDENT2) {
>    // Finally
> }

The or can make things unnecessarily complex, and I've argued in the past that version(x || y) should be allowed.  It's sometimes awkward to try and define a version that means x or y.

But here is essentially the way to do your thingy.

version(IDENT)
{
}
else version(IDENT2)
{
}
else
{
   version=NOT_IDENT_OR_IDENT2;
}

version(NOT_IDENT_OR_IDENT2)
{
  ...
}

or if you only use this in one place, just put the ... inside the else clause.

If you can help it, try to avoid versioning this way.  Versioning should use positive symbols, not negative ones.  I still think an easier OR clause would help quite a bit.  The AND clause is pretty easy, just put multiple version statements on the same line.

-Steve
February 27, 2011
On 2/27/11 3:52 PM, simendsjo wrote:
> I'm having some problems grokking version.
>
> How would I translate this simple C macro?
> #if !defined(IDENT) || !defined(IDENT2)

You are facing a quite common question, with the answer being that there is no simpler way to do this, at least that I know of.

This has to do with both the stage at which version blocks are parsed internally, and with Walter taking a defensive stance on the power of version statements because he feels that the typical C preprocessor constructs are often a source for confusion (sorry if I misquoted you there).

If you need more complex version conditions, however, you could consider mapping versions to manifest constants and using static ifs like this:

version (foo) {
   enum version_foo = true;
} else {
   enum version_foo = false;
}

static if (version_foo || (version_bar && !version_baz) ) {
   …
} else {
   …
}


David
February 27, 2011
On 2/27/11 4:14 PM, Steven Schveighoffer wrote:
> But here is essentially the way to do your thingy.
>
> version(IDENT)
> {
> }
> else version(IDENT2)
> {
> }
> else
> {
> version=NOT_IDENT_OR_IDENT2;
> }
>
> version(NOT_IDENT_OR_IDENT2)
> {
> ...
> }

Wouldn't that be »!(IDENT || IDENT2)«, as opposed to »!IDENT || !IDENT2«?

David
February 27, 2011
On 27.02.2011 16:14, Steven Schveighoffer wrote:
> On Sun, 27 Feb 2011 09:52:01 -0500, simendsjo
> <simen.endsjo@pandavre.com> wrote:
>
>> I'm having some problems grokking version.
>>
>> How would I translate this simple C macro?
>> #if !defined(IDENT) || !defined(IDENT2)
>>
>> I've tried the following:
>> version(!IDENT)
>> > identifier or integer expected, not !
>>
>> !version(IDENT)
>> > Declaration expected, not '!'
>>
>> version(IDENT || IDENT2)
>> > found '||' when expecting ')'
>>
>> version(IDENT) || version(IDENT2)
>> > Declaration expected, not '||'
>>
>>
>> This is just plain ugly:
>> version(IDENT) {
>> } else {
>> version = NOT_IDENT_OR_IDENT2;
>> }
>>
>> version(IDENT2) {
>> } else {
>> version = NOT_IDENT_OR_IDENT2;
>> }
>>
>> version(NOT_IDENT_OR_IDENT2) {
>> // Finally
>> }
>
> The or can make things unnecessarily complex, and I've argued in the
> past that version(x || y) should be allowed. It's sometimes awkward to
> try and define a version that means x or y.
>
> But here is essentially the way to do your thingy.
>
> version(IDENT)
> {
> }
> else version(IDENT2)
> {
> }
> else
> {
> version=NOT_IDENT_OR_IDENT2;
> }
>
> version(NOT_IDENT_OR_IDENT2)
> {
> ...
> }
>
> or if you only use this in one place, just put the ... inside the else
> clause.
>
> If you can help it, try to avoid versioning this way. Versioning should
> use positive symbols, not negative ones. I still think an easier OR
> clause would help quite a bit. The AND clause is pretty easy, just put
> multiple version statements on the same line.
>
> -Steve

Your version is a bit simpler, but it's still confusing. I'm porting a c header, so I won't try to D-ify it.
February 27, 2011
On 27.02.2011 16:18, David Nadlinger wrote:
> On 2/27/11 3:52 PM, simendsjo wrote:
>> I'm having some problems grokking version.
>>
>> How would I translate this simple C macro?
>> #if !defined(IDENT) || !defined(IDENT2)
>
> You are facing a quite common question, with the answer being that there
> is no simpler way to do this, at least that I know of.
>
> This has to do with both the stage at which version blocks are parsed
> internally, and with Walter taking a defensive stance on the power of
> version statements because he feels that the typical C preprocessor
> constructs are often a source for confusion (sorry if I misquoted you
> there).
>
> If you need more complex version conditions, however, you could consider
> mapping versions to manifest constants and using static ifs like this:
>
> version (foo) {
> enum version_foo = true;
> } else {
> enum version_foo = false;
> }
>
> static if (version_foo || (version_bar && !version_baz) ) {
> > } else {
> > }
>
>
> David

Thanks. A nice idea, and it makes the code prettier.
I can even use the same identifier names:

version(IDENT)
    enum IDENT = true;
else
    enum IDENT = false;

version(IDENT2)
    enum IDENT2 = true;
else
    enum IDENT2 = false;

static if(IDENT || IDENT2) {
}

February 27, 2011
On Sun, 27 Feb 2011 15:52:01 +0100, simendsjo wrote:

> I'm having some problems grokking version.
> 
> How would I translate this simple C macro? #if !defined(IDENT) ||
> !defined(IDENT2)
> 
> I've tried the following:
> version(!IDENT)
>  > identifier or integer expected, not !
> 
> !version(IDENT)
>  > Declaration expected, not '!'
> 
> version(IDENT || IDENT2)
>  > found '||' when expecting ')'
> 
> version(IDENT) || version(IDENT2)
>  > Declaration expected, not '||'
> 
> 
> This is just plain ugly:
> version(IDENT) {
> } else {
>    version = NOT_IDENT_OR_IDENT2;
> }
> 
> version(IDENT2) {
> } else {
>    version = NOT_IDENT_OR_IDENT2;
> }
> 
> version(NOT_IDENT_OR_IDENT2) {
>    // Finally
> }

Here's one nice solution to your problem:

http://www.digitalmars.com/d/archives/digitalmars/D/ Improving_version_..._119799.html#N119846

Basically, he defines an isVersion() template which is true if the current version is enabled, and false if not.

-Lars
February 27, 2011
On 27.02.2011 17:27, Lars T. Kyllingstad wrote:
> On Sun, 27 Feb 2011 15:52:01 +0100, simendsjo wrote:
>
>> I'm having some problems grokking version.
>>
>> How would I translate this simple C macro? #if !defined(IDENT) ||
>> !defined(IDENT2)
>>
>> I've tried the following:
>> version(!IDENT)
>>   >  identifier or integer expected, not !
>>
>> !version(IDENT)
>>   >  Declaration expected, not '!'
>>
>> version(IDENT || IDENT2)
>>   >  found '||' when expecting ')'
>>
>> version(IDENT) || version(IDENT2)
>>   >  Declaration expected, not '||'
>>
>>
>> This is just plain ugly:
>> version(IDENT) {
>> } else {
>>     version = NOT_IDENT_OR_IDENT2;
>> }
>>
>> version(IDENT2) {
>> } else {
>>     version = NOT_IDENT_OR_IDENT2;
>> }
>>
>> version(NOT_IDENT_OR_IDENT2) {
>>     // Finally
>> }
>
> Here's one nice solution to your problem:
>
> http://www.digitalmars.com/d/archives/digitalmars/D/
> Improving_version_..._119799.html#N119846
>
> Basically, he defines an isVersion() template which is true if the
> current version is enabled, and false if not.
>
> -Lars


Pretty nice, but I don't like magic strings. I'd rather use my more clunky version.
February 27, 2011
On Sun, 27 Feb 2011 10:20:46 -0500, David Nadlinger <see@klickverbot.at> wrote:

> On 2/27/11 4:14 PM, Steven Schveighoffer wrote:
>> But here is essentially the way to do your thingy.
>>
>> version(IDENT)
>> {
>> }
>> else version(IDENT2)
>> {
>> }
>> else
>> {
>> version=NOT_IDENT_OR_IDENT2;
>> }
>>
>> version(NOT_IDENT_OR_IDENT2)
>> {
>> ...
>> }
>
> Wouldn't that be »!(IDENT || IDENT2)«, as opposed to »!IDENT || !IDENT2«?
>
> David

Yes, my version is wrong.  simendsjo's version is probably the only way to do it.  It's difficult to reason about negative booleans.

-Steve
February 28, 2011
On Sunday 27 February 2011 07:18:29 David Nadlinger wrote:
> On 2/27/11 3:52 PM, simendsjo wrote:
> > I'm having some problems grokking version.
> > 
> > How would I translate this simple C macro?
> > #if !defined(IDENT) || !defined(IDENT2)
> 
> You are facing a quite common question, with the answer being that there is no simpler way to do this, at least that I know of.
> 
> This has to do with both the stage at which version blocks are parsed internally, and with Walter taking a defensive stance on the power of version statements because he feels that the typical C preprocessor constructs are often a source for confusion (sorry if I misquoted you there).

Yeah. Essentially, Walter believes that how versioning is often done in C with #ifdefs is inherently wrong. If you're doing complicated versioning statements like that you really need to rethink how you're doing things. You shouldn't need them. Granted, converting from C/C++ can be quite a bit messier in that regard than writing D code from scratch, but still, in general, if you need complicated versioning statements, then you're probably going about it the wrong way. Though, on occasion, it definitely _would_ be nice to have the ability to || version identifiers together, and I'm not sure what the problem with that would be other than the fact that version statements just don't work that way and their implementation would probably have to be redesigned a fair bit to allow for it. Walter is _definitely_ against the negation of version identifiers and stuff like that though.

- Jonathan M Davis
« First   ‹ Prev
1 2