assert()

The assert function produces an assertion – a type of execution interrupt specially designed for development and debugging of applications – if the boolean expression passed as first (and only required) parameter evaluates to false.

Assertions are helpful to, well, assert certain conditions that code assumes to be true, for debugging purposes. Assertions are not designed to be used in production versions of your code, or to validate external input processed by your application (see below).

Syntax:

method assert(expression: Boolean; description: String := nil);
void assert(bool expression, string description = null);
func assert(_ expression: Bool, _ description: String? = default)
void assert(bool expression, string description = null);

If the boolean expression evaluates to false, an assertion interrupt occurs and shows you the location of the assert, as well as the optional message.

For example, consider the following code:

var x: Integer := 5;
assert(x < 5, 'assertion test');
int x = 5;
assert(x < 5, "assertion test");
x: Int = 5
assert(x < 5, "assertion test");
int x = 5;
assert(x < 5, "assertion test");

When the above code is compiled in Debug mode and run, an assertion dialog is shown, because the condition is violated (x is not smaller than 5).

Appropriateness of Assertions

Assertion interrupts should not be confused with program exceptions – they are a different thing entirely. Depending on your OS and runtime environment, you have the option of ignoring the assertion entirely, going into debug mode, or terminating your app.

Note: When not running in the debugger, assertions are always fatal. Therefore, you should use assertions only to validate code assumptions and to help you debug coding errors (that without assertion might still result in a bug or a crash, just one that would be harder to pinpoint). You should *never use assertions to check for conditions that are not program bugs.

For example, don't rely on assertions to validate user input or data received over the network or read from a file, as an app needs to be able to handle bad input, and bad input is not a program bug.

On the flip side, if you have data generated by a routine in your program that is (supposedly) guaranteed to be valid, it is appropriate to use an assertion to check that data, because bad data would indicate a program bug.

Assertions and Oxygene Class Contracts

The Oxygene language has a feature called Class Contracts that allows you to encode assumptions abut valid data in a more language-integrated fashion, as Invariants on a class itself, and as Pre- and Post-Conditions for individual methods.

Class Contracts use the assert() function under the hood, and everything discussed in this topic applies to Class Contracts as well.

Enabling Assertions

Your production code should of course be correct enough to never hit any assertions. That said, it's usually a good idea to disable assertions for production builds, both to save the extra runtime overhead of these checks, and to avoid your end-users seeing assertions if there is a bug left that your testing did not catch.

By default, assertions are enabled for the DEBUG configuration of Elements projects, and disabled for the RELEASE configuration, in Project Settings. You can of course change that if you wish to ship with assertions.

With the "Enable Asserts" option off, all calls to assert() and any Oxygene Class Contracts will be ignored by the compiler, and no code will be emitted for them. For that reason it is important to avoid relying on side effects from the boolean expression. Consider for example:

var validNumberString: String := '5';
var number: Integer;
assert(Integer.TryParse(validNumberString, out number)); // DANGER! This won't happen with assertions off
writeLn(number);
string validNumberString = "5";
int number;
assert(int.TryParse(validNumberString, out number)); // DANGER! This won't happen with assertions off
writeLn(number);
let validNumberString: String = "5"
var number: Int = -1;
assert(Int.TryParse(validNumberString, &number)); // DANGER! This won't happen with assertions off
println(number);
String validNumberString = "5";
int number;
assert(int.TryParse(validNumberString, out number)); // DANGER! This won't happen with assertions off
writeLn(number);

See Also