# Assertions and Argument Checking (/contributing/assertions)



LVGL provides two sets of macros for validating conditions at runtime:
**assertions** and **argument checking**. This page explains when and how to use
each within LVGL's codebase.

Overview [#overview]

| Feature           | LV\_ASSERT                  | LV\_CHECK\_ARG         |
| ----------------- | --------------------------- | ---------------------- |
| Purpose           | Catch programming errors    | Validate runtime input |
| On failure        | Halts (LV\_ASSERT\_HANDLER) | Configurable action    |
| Log level         | Error                       | Warning                |
| Recovery possible | No                          | Yes / Maybe            |
| Typical use       | Internal invariants         | API input validation   |

**Use assertions** for conditions that indicate bugs in the code—situations
that should never happen if the code is correct.

**Use argument checking** for conditions that might legitimately fail at runtime
(e.g., user-provided input, resource availability) and require graceful handling.

Assertions [#assertions]

Assertions check for programming errors and halt the program when they fail.
They are typically enabled only in debug builds and may be disabled in release builds.

Configuration [#configuration]

Enable assertions in `lv_conf.h`:

* <ApiLink name="LV_USE_ASSERT_NULL" /> - Check for NULL pointers
* <ApiLink name="LV_USE_ASSERT_MALLOC" /> - Check for failed memory allocations
* <ApiLink name="LV_USE_ASSERT_MEM_INTEGRITY" /> - Check memory integrity

Configure the assert handler with <ApiLink name="LV_ASSERT_HANDLER" />. The default
behavior is `while(1);` which halts the program.

Usage [#usage]

<ApiLink name="LV_ASSERT" />

Basic assertion with the condition stringified in the log message:

```c title=" " lineNumbers=1
LV_ASSERT(pi > 0);
```

<ApiLink name="LV_ASSERT_MSG" />

Assertion with a plain string message:

```c title=" " lineNumbers=1
LV_ASSERT_MSG(pi > 0, "pi should be positive");
```

<ApiLink name="LV_ASSERT_FORMAT_MSG" />

Assertion with a printf-style format message:

```c title=" " lineNumbers=1
LV_ASSERT_FORMAT_MSG(pi > 0, ": was %f", pi);
```

Specialized Assertions [#specialized-assertions]

<ApiLink name="LV_ASSERT_NULL" />

Check that a pointer is not NULL:

```c title=" " lineNumbers=1
LV_ASSERT_NULL(obj);
```

<ApiLink name="LV_ASSERT_MALLOC" />

Check that a memory allocation succeeded:

```c title=" " lineNumbers=1
void * buf = lv_malloc(size);
LV_ASSERT_MALLOC(buf);
```

<ApiLink name="LV_ASSERT_MEM_INTEGRITY" />

Check that LVGL's memory pool is not corrupted:

```c title=" " lineNumbers=1
LV_ASSERT_MEM_INTEGRITY();
```

Argument Checking [#argument-checking]

The <ApiLink name="LV_CHECK_ARG" /> macro provides a flexible approach for validating
function arguments at runtime: it logs a warning and allows you to specify a
recovery action (such as returning from a function or continuing with a fallback).

This macro is useful for:

* Input validation at the start of functions
* Checking preconditions without halting the program
* Defensive programming with graceful error handling
* Logging invariant violations that may not be critical but should be noted

Configuration [#configuration-1]

In `lv_conf.h`:

* <ApiLink name="LV_USE_CHECK_ARG" /> - Set to `1` to enable, `0` to disable.
  When disabled, all `LV_CHECK_ARG` calls compile to nothing.
* <ApiLink name="LV_CHECK_ARG_ASSERT_ON_FAIL" /> - Set to `1` to also call
  `LV_ASSERT_HANDLER` on failure (before the action is executed).

The macro uses the [Logging](/debugging/log) system to output warnings.
Make sure logging is enabled by setting <ApiLink name="LV_USE_LOG" /> to `1`.

Usage [#usage-1]

<ApiLink name="LV_CHECK_ARG" />

Takes a condition, an action to execute on failure, and optional printf-style
arguments for the log message:

```c title=" " lineNumbers=1
void draw_to_display(lv_obj_t * display, int len)
{
    /* Return early if display is NULL */
    LV_CHECK_ARG(display != NULL, return, ": display must be provided");

    /* Return -1 if len is invalid, logging the actual value */
    LV_CHECK_ARG(len % 2 == 0, return, ": need even data points, but got %d", (int)len);
}

int get_width(lv_obj_t * obj)
{
    /* Return -1 if obj is NULL */
    LV_CHECK_ARG(obj != NULL, return -1, "tried to get width of NULL object");
    /* ... */
}
```

The condition is stringified and included in the log message, so you can see
exactly what check failed. Only supply a format string and arguments if you
want to include additional context beyond the condition itself.

Using `break` as the action in a loop:

```c title=" " lineNumbers=1
for(int i = 0; i < count; i++) {
    LV_CHECK_ARG(data[i] != NULL, break, ": NULL at index %d", i);
    /* ... */
}
```

Macros Reference [#macros-reference]

Assertions [#assertions-1]

| Macro                                      | Description                               |
| ------------------------------------------ | ----------------------------------------- |
| <ApiLink name="LV_ASSERT" />               | Assert condition; on failure log and halt |
| <ApiLink name="LV_ASSERT_MSG" />           | Assert with plain string message          |
| <ApiLink name="LV_ASSERT_FORMAT_MSG" />    | Assert with printf-style format message   |
| <ApiLink name="LV_ASSERT_NULL" />          | Assert pointer is not NULL (if enabled)   |
| <ApiLink name="LV_ASSERT_MALLOC" />        | Assert allocation succeeded (if enabled)  |
| <ApiLink name="LV_ASSERT_MEM_INTEGRITY" /> | Assert memory pool integrity (if enabled) |

Argument Checking [#argument-checking-1]

| Macro                           | Description                                        |
| ------------------------------- | -------------------------------------------------- |
| <ApiLink name="LV_CHECK_ARG" /> | Check condition; on failure log and execute action |
