Invariants for methods

Jonathan M Davis jmdavisProg at gmx.com
Thu Nov 18 13:43:15 PST 2010


On Thursday 18 November 2010 13:29:15 Jens Mueller wrote:
> Jonathan M Davis wrote:
> > On Thursday 18 November 2010 12:08:19 Jens Mueller wrote:
> > > I like it.
> > > Thanks.
> > > What I'd even like better (because contracts are release specific):
> > > release {
> > > 
> > >     const currentWidth = width;
> > >     const currentHeight = height;
> > >     scope (exit) {
> > >     
> > >         assert(currentWidth == width);
> > >         assert(currentHeight == height);
> > >     
> > >     }
> > > 
> > > }
> > > But that does not work. Why do we have special syntax for debug but not
> > > for release. Both seem to me very similar. In the end I tend to think
> > > release/debug as a shorthand for version(release/debug). But that's
> > > not quite right. Somehow it's allowed to write version(unittest) {}
> > > equivalently for unittest {}. But for debug/release there is no such
> > > thing. Why this asymmetry?
> > 
> > One thing that you need to realize is that the -release and -debug flags
> > are _completely_ unrelated. You can use none, or one, or even both.
> > 
> > -release disables assertions (other than assert(0)) - including removing
> > all pre-conditions, post-condition, and invariants - and removes array
> > bounds checking for @system and @trusted functions.
> > 
> > -debug enables all debug blocks.
> > 
> > So, you can have
> > 
> > * Neither flag: All assertions, contracts, and array bounds checking are
> > enabled, and debug blocks are not compiled in.
> > 
> > * -release only: All assertions, contracts, and array bounds checking for
> > @system and @trusted functions are removed. debug blocks are not compiled
> > in.
> > 
> > * -debug only: All assertions, contracts, and array bounds checking are
> > enabled, and debug blocks are compiled in.
> > 
> > * Both flags: All assertions, contracts, and array bounds checking in
> > @system and @trusted functions are removed. debug blocks are compiled
> > in.
> 
> I think unittest should be added to this list. Because it can cause more
> confusion.
> 
> > So, the flags in question are quite confusing really, and talking about
> > debug mode doesn't actually make sense when you think about it. You have
> > release mode and non-release mode. And you either have debug blocks
> > enabled or you don't. And on top of that, you have whether debug symbols
> > are enabled or not (even worse, there are two different flags for
> > enabling debug symobls: -g and -gc). So, the flags as they are make the
> > whole release vs debug build thing really confusing, and they're
> > probably not terms that really should be used unless you're talking
> > about your specific build process and the specific set of flags that you
> > use for building for release builds and the specific set of flags that
> > you use for debug builds. But talking about release and debug builds is
> > so ingrained in people, that they keep using the terms anyway, and most
> > people probably don't quite understand the imprecision of the terms with
> > regards to dmd.
> 
> I totally agree with you and I think one should fix dmd's help message.
> I would love to see
> -release       same as -nocontracts -noasserts -noboundscheck
> -debugging     same as -debug -unittest -contracts -asserts -boundscheck
> -testing       same as -unittest -contracts, -asserts, -boundscheck
> 
> These switches basically configure your software (which code to
> compile). And above you find the typical configurations for release,
> testing and debugging. One could leave out the defaults.
> 
> Having orthogonal command line switches:
> -(no)boundscheck    compile in array bound checks
> -(no)contracts      compile in contracts
> -(no)debug          compile in debug
> -(no)unittest       compile in unittest
> -(no)assert         -noassert causes assert(<compile-time constant>)
>                     to be translated to hlt
> with some sensible default (but only disabling the default might be
> implemented) e.g.
> -nounittest
> This we have already. Because we -unittest.
> -nodebug
> This we have as well via -debug.
> -boundscheck
> This too (-noboundscheck).
> -contracts
> Missing: -nocontracts
> -assert
> Missing: -noasserts
> 
> But I think this can lead to something like -unittest -noassert which is
> rather strange. Don't know. Would still go for it.
> 
> And now as you say one can specify -g for debug symbols or -O for
> optimization.
> In summary there are two things to consider:
> 1. What code will be included? (debug, unittest, contracts, assertions,
>    boundschecking, and version=xxx)
> 2. How will the code be generated? (with debug symbols -g, -gc;
>    optimized -0)
> 
> Typical release code is built via -release -O I'll guess. It's true
> -release does not do a release build as one expects. Same for
> -debugging. Because -g is missing. Better names would help here. But
> it's difficult to change that now, isn't it? That's why better dmd
> --help output should be sufficient.

I don't think that they're all that hard to understand and use as it is, but I 
do think that there is often a fair bit of confusion about them at first, and 
there is _definitely_ confusion about it in discussions because of terms like 
"debug build" which are arguably next to meaningless but get used all the time 
anyway.

- Jonathan M Davis


More information about the Digitalmars-d mailing list