www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Conditional compilation for non-release version

reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
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
Apr 28 2012
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
Apr 28 2012
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
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; }());
Apr 28 2012
prev sibling next sibling parent "F i L" <witte2008 gmail.com> writes:
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.
Apr 28 2012
prev sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
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.
Apr 28 2012