What Is the "Assert" Function

What is the assert function?

assert will terminate the program (usually with a message quoting the assert statement) if its argument turns out to be false. It's commonly used during debugging to make the program fail more obviously if an unexpected condition occurs.

For example:

assert(length >= 0);  // die if length is negative.

You can also add a more informative message to be displayed if it fails like so:

assert(length >= 0 && "Whoops, length can't possibly be negative! (didn't we just check 10 lines ago?) Tell jsmith");

Or else like this:

assert(("Length can't possibly be negative! Tell jsmith", length >= 0));

When you're doing a release (non-debug) build, you can also remove the overhead of evaluating assert statements by defining the NDEBUG macro, usually with a compiler switch. The corollary of this is that your program should never rely on the assert macro running.

// BAD
assert(x++);

// GOOD
assert(x);
x++;

// Watch out! Depends on the function:
assert(foo());

// Here's a safer way:
int ret = foo();
assert(ret);

From the combination of the program calling abort() and not being guaranteed to do anything, asserts should only be used to test things that the developer has assumed rather than, for example, the user entering a number rather than a letter (which should be handled by other means).

What is the use of assert in Python?

The assert statement exists in almost every programming language. It has two main uses:

  1. It helps detect problems early in your program, where the cause is clear, rather than later when some other operation fails. A type error in Python, for example, can go through several layers of code before actually raising an Exception if not caught early on.

  2. It works as documentation for other developers reading the code, who see the assert and can confidently say that its condition holds from now on.

When you do...

assert condition

... you're telling the program to test that condition, and immediately trigger an error if the condition is false.

In Python, it's roughly equivalent to this:

if not condition:
raise AssertionError()

Try it in the Python shell:

>>> assert True # nothing happens
>>> assert False
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError

Assertions can include an optional message, and you can disable them when running the interpreter.

To print a message if the assertion fails:

assert False, "Oh no! This assertion failed!"

Do not use parenthesis to call assert like a function. It is a statement. If you do assert(condition, message) you'll be running the assert with a (condition, message) tuple as first parameter.

As for disabling them, when running python in optimized mode, where __debug__ is False, assert statements will be ignored. Just pass the -O flag:

python -O script.py

See here for the relevant documentation.

Is using assert() in C++ bad practice?

Assertions are entirely appropriate in C++ code. Exceptions and other error handling mechanisms aren't really intended for the same thing as assertions.

Error handling is for when there's a potential for recovering or reporting an error nicely to the user. For example if there's an error trying to read an input file you may want to do something about that. Errors could result from bugs, but they could also simply be the appropriate output for a given input.

Assertions are for things like checking that an API's requirements are met when the API wouldn't normally be checked, or for checking things the developer believes he's guaranteed by construction. For example if an algorithm requires sorted input you wouldn't normally check that, but you might have an assertion to check it so that debug builds flag that kind of bug. An assertion should always indicate an incorrectly operating program.


If you're writing a program where an unclean shutdown could cause a problem then you may want to avoid assertions. Undefined behavior strictly in terms of the C++ language doesn't qualify as such a problem here, since hitting an assertion is probably already the result of undefined behavior, or the violation of some other requirement which could prevent some clean-up from working properly.

Also if you implement assertions in terms of an exception then it could potentially be caught and 'handled' even though this contradicts the very purpose of the assertion.

What assert do in dart?

Main purpose of assert is testing conditions during debugging/development.

Let's think about a real example:

class Product {
Product({
required this.id,
required this.name,
required this.price,
this.size,
this.image,
this.weight,
}) : assert(id > 0),
assert(name.isNotEmpty),
assert(price > 0.0);

final int id;
final String name;
final double price;
final String? size;
final String? image;
final int? weight;
}

We have a Product class and fields like id, name and price are mandatory but other fields can be handled by generic values as you guess. By asserting required fields, you'll test this data class during debugging/development. Keep in the mind, all asserts ignored in release/production mode;

From the dart.dev#assert:

In production code, assertions are ignored, and the arguments to assert aren’t evaluated.

Comparing to writing tests, even though they are not the same thing, asserts can be very handy with minimal effort, so be generous for writing asserts especially if you don't write tests, it usually rewards you.

Additionally, since constants like kDebugMode, kReleaseMode are part of package:flutter/foundation.dart, another use case is debugMode specific codes in Non-Flutter applications. Let's have a look this code:

bool get isDebugMode {
bool value = false;
assert(() {
value = true;
//you can execute debug-specific codes here
return true;
}());
return value;
}

At first it may look confusing but it's a tricky but simple code. An anonymous closure always returns true, so we don't throw any error in any case. Since compiler eliminates the assert statements in release mode, that closure only run in debug mode and mutate the value variable.

Similarly, you can throw in only debug, from Flutter source code:

void addAll(Iterable<E> iterable) {
int i = this.length;
for (E element in iterable) {
assert(this.length == i || (throw ConcurrentModificationError(this)));
add(element);
i++;
}
}

That means, it throws only in debug mode, intended for usage in testing your logic.

Nullable Example

For the versions of Dart before 2.12, your typical example should be look like this:

import 'package:meta/meta.dart';

class Product {
final int id;
final String name;
final int price;
final String size;
final String image;
final int weight;

const Product({
@required this.id,
@required this.name,
@required this.price,
this.size,
this.image,
this.weight,
}) : assert(id != null && name != null && price != null);
}

C# - What does the Assert() method do? Is it still useful?

In a debug compilation, Assert takes in a Boolean condition as a parameter, and shows the error dialog if the condition is false. The program proceeds without any interruption if the condition is true.

If you compile in Release, all Debug.Assert's are automatically left out.

Why is assert a macro and not a function?

The simple explanation would be that the standard requires assert to be a macro, if we look at the draft C99 standard(as far as I can tell the sections are the same in draft C11 standard as well) section 7.2 Diagnostics paragraph 2 says:

The assert macro shall be implemented as a macro, not as an actual
function. If the macro definition is suppressed in order to access an
actual function, the behavior is undefined.

Why does it require this, the rationale given in Rationale for International Standard—Programming Languages—C is:

It can be difficult or impossible to make assert a true function, so it is restricted to macro
form.

which is not very informative, but we can see from other requirements why. Going back to section 7.2 paragraph 1 says:

[...]If NDEBUG is defined as a macro name at the point in the source file
where is included, the assert macro is defined simply as

#define assert(ignore) ((void)0)

The assert macro is redefined according to the current state of NDEBUG
each time that is included.

This is important since it allows us an easy way to turn off assertions in release mode where you may want to take the cost of potentially expensive checks.

and the second important requirement is that it is required to use the macros __FILE__, __LINE__ and __func__, which is covered in section 7.2.1.1 The assert macro which says:

[...] the assert macro writes information about the particular call
that failed [...] the latter are respectively the values of the
preprocessing macros __FILE_ _ and __LINE_ _ and of the identifier
__func_ _) on the standard error stream in an implementation-defined format.165) It then calls the abort function.

where footnote 165 says:

The message written might be of the form:

Assertion failed: expression, function abc, file xyz, line nnn.

Having it as a macro allows the macros __FILE__ etc... to be evaluated in the proper location and as Joachim points out being a macro allows it to insert the original expression in the message it generates.

The draft C++ standard requires that the contents of the cassert header are the same as the assert.h header from Standrd C library:

The contents are the same as the Standard C library header .

See also: ISO C 7.2.

Why (void)0?

Why use (void)0 as opposed to some other expression that does nothing? We can come up with a few reasons, first this is how the assert synopsis looks in section 7.2.1.1:

void assert(scalar expression);

and it says (emphasis mine):

The assert macro puts diagnostic tests into programs; it expands to a void expression.

the expression (void)0 is consistent with the need to end up with a void expression.

Assuming we did not have that requirement, other possible expressions could have undesirable effects such as allowing uses of assert in release mode that would not be allowed in debug mode for example using plain 0 would allow us to use assert in an assignment and when used correctly would likely generate an expression result unused warning. As for using a compound statement as a comment suggests, we can see from C multi-line macro: do/while(0) vs scope block that they an have undesirable effects in some cases.

What is “assert” in JavaScript?

There is no standard assert in JavaScript itself. Perhaps you're using some library that provides one; for instance, if you're using Node.js, perhaps you're using the assertion module. (Browsers and other environments that offer a console implementing the Console API provide console.assert.)

The usual meaning of an assert function is to throw an error if the expression passed into the function is false; this is part of the general concept of assertion checking. Usually assertions (as they're called) are used only in "testing" or "debug" builds and stripped out of production code.

Suppose you had a function that was supposed to always accept a string. You'd want to know if someone called that function with something that wasn't a string (without having a type checking layer like TypeScript or Flow). So you might do:

assert(typeof argumentName === "string");

...where assert would throw an error if the condition were false.

A very simple version would look like this:

function assert(condition, message) {
if (!condition) {
throw message || "Assertion failed";
}
}

Better yet, make use of the Error object, which has the advantage of collecting a stack trace and such:

function assert(condition, message) {
if (!condition) {
throw new Error(message || "Assertion failed");
}
}

What does the Java assert keyword do, and when should it be used?

Assertions (by way of the assert keyword) were added in Java 1.4. They are used to verify the correctness of an invariant in the code. They should never be triggered in production code, and are indicative of a bug or misuse of a code path. They can be activated at run-time by way of the -ea option on the java command, but are not turned on by default.

An example:

public Foo acquireFoo(int id) {
Foo result = null;
if (id > 50) {
result = fooService.read(id);
} else {
result = new Foo(id);
}
assert result != null;

return result;
}

C++ assert implementation in assert.h

Look at this line:

extern void __assert (const char *msg, const char *file, int line);

__assert is function that takes an assertion message, a file name and a line number as arguments. Basically, this is the method that prints out the error message and terminates the program when the assertion failed.

Then look at the macro definition above:

#define assert(EX) (void)((EX) || (__assert (#EX, __FILE__, __LINE__),0))

It defines the assert(EX) macro so, it first checks the EX expression and (because of the short-circuit operation of the C++ || operator) only if it fails, it calls the __assert function and passes the failed assertion exception as a string, and the exact location of the assert() method call in your source files. With this preprocessor trickery the assertion library achieves that when you type the following in your program

assert(a == 0);

and your assertion fails during the program run, you get the detailed

Assertion failed: a == 0 at program.c, line 23

error message that helps you to identify the exact location where the assertion was failing in your code.

The (void) part is just for make sure that the compiler won't put up some warnings about the unused result of the (EX) || 0 expression, see the other answers, the guys explained it well.

The remaining preprocessor define NDEBUG is used to turn of assertion generation at all compile-time, you your resulting executable will be smaller and faster.



Related Topics



Leave a reply



Submit