www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Version very simple?

reply simendsjo <simen.endsjo pandavre.com> writes:
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 }
Feb 27 2011
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
Feb 27 2011
next sibling parent David Nadlinger <see klickverbot.at> writes:
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
Feb 27 2011
prev sibling next sibling parent simendsjo <simen.endsjo pandavre.com> writes:
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.
Feb 27 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
Feb 27 2011
prev sibling next sibling parent reply David Nadlinger <see klickverbot.at> writes:
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
Feb 27 2011
next sibling parent simendsjo <simen.endsjo pandavre.com> writes:
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) { }
Feb 27 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Feb 27 2011
prev sibling next sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
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
Feb 27 2011
parent simendsjo <simen.endsjo pandavre.com> writes:
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.
Feb 27 2011
prev sibling parent Trass3r <un known.com> writes:
Note that negation and logical and can basically be simulated:

!bla ->
version(bla) {} else ...

bla && blub ->
version(bla) version(blub) {...}
Feb 28 2011