Skip to content

Commit

Permalink
Merge pull request #624 from quickfur/assert_doc
Browse files Browse the repository at this point in the history
Improve assert expression documentation.
  • Loading branch information
AndrejMitrovic committed Oct 2, 2014
2 parents 01a407c + 279d262 commit cd99fd8
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 31 deletions.
31 changes: 17 additions & 14 deletions contracts.dd
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,27 @@ $(COMMENT <img src="images/d4.gif" alt="Contracts make D bug resistant" border=0

$(H2 Assert Contract)

The most basic contract is the
$(P The most basic contract is the
$(GLINK2 expression, AssertExpression).
An $(B assert) inserts a checkable expression into
the code, and that expression must evaluate to true:
An $(B assert) declares an expression that must evaluate to true:)
------
assert(expression);
------
C programmers will find it familiar. Unlike C, however, an <code>assert</code>
in function bodies
works by throwing an <code>AssertError</code>,
which can be caught and handled. Catching the contract violation is useful
when the code must deal with errant uses by other code, when it must be
failure proof, and as a useful tool for debugging.

$(P When compiling for release, the assert code is not generated.
The special $(D assert(0)) expression, however, is generated even in
release mode. See the $(GLINK2 expression, AssertExpression) documentation
for more information.)
$(P As a contract, an $(D assert) represents a guarantee that the code
$(I must) uphold. Any failure of this expression represents a logic
error in the code that must be fixed in the source code. A program for
which the assert contract is false is, by definition, invalid, and
therefore has undefined behaviour.)

$(P As a debugging aid, the compiler may insert a runtime check to
verify that the expression is indeed true. If it is false, an $(D
AssertError) is thrown. When compiling for release, this check is not
generated. The special $(D assert(0)) expression, however, is
generated even in release mode. See the $(GLINK2 expression,
AssertExpression) documentation for more information.)

$(P The compiler is free to assume the assert expression is true and
optimize subsequent code accordingly.)

$(H2 Pre and Post Contracts)

Expand Down
7 changes: 4 additions & 3 deletions dcompiler.dd
Original file line number Diff line number Diff line change
Expand Up @@ -683,9 +683,10 @@ dmd -cov -unittest myprog.d
)
$(SWITCH $(B -release),

compile release version, which means not generating
code for contracts and asserts. Array bounds checking
is not done for system and trusted functions.
compile release version, which means not emitting run-time
checks for contracts and asserts. Array bounds checking is not
done for system and trusted functions, and assertion failures
are undefined behaviour.
)
$(SWITCH $(B -run) $(I srcfile args...)
compile, link, and run the program $(I srcfile) with the
Expand Down
40 changes: 27 additions & 13 deletions expression.dd
Original file line number Diff line number Diff line change
Expand Up @@ -1509,19 +1509,33 @@ $(GNAME AssertExpression):
$(D assert $(LPAREN)) $(GLINK AssignExpression) $(D ,) $(GLINK AssignExpression) $(D $(RPAREN))
)

$(P Asserts evaluate the $(I AssignExpression).
If it evaluates to a non-null class reference, the class invariant is run.
Otherwise, if it evaluates to a non-null pointer to a struct, the struct invariant is run.
Otherwise, if the result is false,
an $(D AssertError) is thrown. If the result is true, then no
exception is thrown.
It is an error if the $(I expression) contains any side effects
that the program depends on. The compiler may optionally not
evaluate assert expressions at all.
The result type of an assert expression is $(D void).
Asserts are a fundamental part of the
$(DDLINK contracts, Contract Programming, Contract Programming)
support in D.
$(P The assert expression is used to declare conditions that the
programmer asserts must hold at that point in the program if the
program logic has been correctly implemented. It can be used both as a
debugging tool and as a way of communicating to the compiler facts
about the code that it may employ to produce more efficient code.)

$(P Programs for which $(I AssignExpression) is false are invalid.
Subsequent to such a false result, the program is in an invalid,
non-recoverable state.)

$(P As a debugging tool, the compiler may insert checks to verify that
the condition indeed holds by evaluating $(I AssignExpression) at
runtime. If it evaluates to a non-null class reference, the class
invariant is run. Otherwise, if it evaluates to a non-null pointer to
a struct, the struct invariant is run. Otherwise, if the result is
false, an $(D AssertError) is thrown. If the result is true, then no
exception is thrown. In this way, if a bug in the code causes the
assertion to fail, execution is aborted, prompting the programmer to
fix the problem.)

$(P It is implementation defined whether the $(I AssignExpression) is
evaluated at run time or not. Programs that rely on side effects of $(I
AssignExpression) are invalid.)

$(P The result type of an assert expression is $(D void). Asserts are
a fundamental part of the $(DDLINK contracts, Contract Programming,
Contract Programming) support in D.
)

$(P The expression $(D assert(0)) is a special case; it
Expand Down
2 changes: 1 addition & 1 deletion version.dd
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ $(H3 $(LEGACY_LNAME2 PredefinedVersions, predefined-versions, Predefined Version
$(TROW $(ARGS $(D D_Version2)) , $(ARGS This is a D version 2 compiler))
$(TROW $(ARGS $(D D_NoBoundsChecks)) , $(ARGS Array bounds checks are disabled (command line $(DPLLINK dmd-windows.html#switches, switch) $(D -noboundscheck))))
$(TROW $(ARGS $(D unittest)) , $(ARGS $(DDLINK unittest, Unit Tests, Unit tests) are enabled (command line $(DPLLINK dmd-windows.html#switches, switch) $(D -unittest))))
$(TROW $(ARGS $(D assert)) , $(ARGS assert expressions are enabled))
$(TROW $(ARGS $(D assert)) , $(ARGS Checks are being emitted for assert expressions))
$(TROW $(ARGS $(D none)) , $(ARGS Never defined; used to just disable a section of code))
$(TROW $(ARGS $(D all)) , $(ARGS Always defined; used as the opposite of $(D none)))
)
Expand Down

0 comments on commit cd99fd8

Please sign in to comment.