Monthly Archives: September 2016

Assertions in Basic+

For those of you who have done any Java or C/C++ programming in the past, assertions may be a familiar programming construct. For those who have not, an assertion is simply a way of embedding tests in your programs to check that a condition is true: if the condition evaluates to false then the program stops to display a message informing you of the failure, and presents a set of choices for dealing with it.

Assertions are basically “sanity checks” that you can employ anywhere in your programs to ensure that the state of your data is as you expect it.  You should use normal error-handling code for errors you expect; you should use assertions for errors that should never occur.

The $assert() statement

In order to support assertions Basic+ a new statement, “$assert” has been introduced into Basic+. This takes a simple comparison expression as an argument like so:

$assert( a > 3 )

The statement above checks that the value of the variable “a” is greater than 3.  If so then the program continues as normal, otherwise an assertion is raised and the assert message displayed.

When passing expressions to the $assert statement ensure you keep them simple.  The $assert is effectively turned into an “if () else” statement when it is compiled, so the resulting runtime code from the example above looks like this:

if ( a > 3 ) else <show assert message>

Therefore you can only pass what you would legally be able to pass to the normal “if” statement.

The $assert_here statement

This statement is an extension of the normal $assert statement and is used to simply assert without testing for an expression.  This is commonly used in an “end else” clause when you enter an unexpected code branch.

It has two forms:

  • $assert_here
  • $assert_here( <text> )

The latter form takes a text string (you don’t have to quote it) like so:

if bLen( winID ) then
   // All good
end else
   // We can't get here amiright?
   $assert_here( winID is null - how did this happen? )

Failed assertions

If the assertion fails you are presented with a message that looks like this:

Assertion message

Assertion message

It tells you the program name, the line number and the expression that caused the failure and gives you three options for processing:

  • Abort – This stops all program execution and returns the system to an idle state.  Just as if you had hit the debugger and then immediately closed it.
  • Debug – This loads the debugger at the point of the assertion.
  • Ignore – This continues the program execution as normal.

There is also a checkbox that allows you to turn off all assertions for the rest of the session.

Note that if you are running a program from the system monitor the assertion dialog looks slightly different as we rely on the Windows MessageBox function to display the error instead:

Assertion MessageBox

Assertion MessageBox

As you can see, the “Debug” button is replaced by a “Retry” button, but they both perform the same function.

Currently assertion messages will not display outside of event context, due to the fact that the message needs a UI to display, and if called from something like a web-server this would be problematic.  In this case assertions are ignored.

Disabling assertions

Assertions present a tidy way to deal with some problems without crashing straight into the debugger, but even so you may not not want your customers to see them in your released code.  In this case you ensure they are never executed by using one of the following methods:

Disabling assertions with the SetDebugger() function

The SetDebugger function can be used to programmatically turn assertions on or off at runtime using its “ASSERT” method.  This can be used when your application is started, and then turned on later for diagnostic purposes if you wish.

$insert logical

// Turn off assertions at runtime
call SetDebugger( "ASSERT", FALSE$ )

// Turn assertions back on
call SetDebugger( "ASSERT", TRUE$ )

Disabling assertions with the compiler

You can also disable assertions when compiling, in which case the checks are never included in the object code.  To do this simply use the NOASSERT token with the #define statement like so:

#define NOASSERT

You can add this to individual programs as you wish,  or to an IDE build configuration, or to the compiler IFDEF list itself if you call it manually.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).