nros C API
Lightweight ROS 2 client for embedded real-time systems
Loading...
Searching...
No Matches
Macros
serialization_format.h File Reference

RFC-0088 D5 — the linked backend's serialization format, as a compile-time fact the C API can assert on. More...

#include "nros/nros_generated.h"
Include dependency graph for serialization_format.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define NROS_ASSERT_MESSAGE_FORMAT(msg_format_id, type_literal)
 
#define NROS_SERIALIZATION_FORMAT_ID_CDR   1
 
#define NROS_SERIALIZATION_FORMAT_ID_UORB   2
 
#define NROS_STATIC_ASSERT(cond, msg)
 
#define NROS_STATIC_ASSERT_CAT(a, b)   NROS_STATIC_ASSERT_CAT_(a, b)
 
#define NROS_STATIC_ASSERT_CAT_(a, b)   a##b
 
#define NROS_STATIC_ASSERT_TAG_   __LINE__
 

Detailed Description

RFC-0088 D5 — the linked backend's serialization format, as a compile-time fact the C API can assert on.

ROS 2 asks rmw_get_serialization_format() at run time because it resolves its typesupport through dlopen. nano-ros does not dlopen, so the answer is already known when the image is compiled: exactly one backend is linked, and one backend speaks exactly one encoding.

NROS_SERIALIZATION_FORMAT_ID is generated — it is cbindgen output in nros/nros_generated.h, lowered from nros_c::constants, whose value is proven equal to nros_node::session::IMAGE_SERIALIZATION_FORMAT_ID by a const _ in that module. So the macro cannot silently disagree with the backend this image links: a backend whose format is not the one mirrored there fails the Rust build with a message naming the drift.

NROS_SERIALIZATION_FORMAT is its cross-image identity string, derived here from the discriminant. RFC-0088 D2 is the reason for that direction: the string is the identity that crosses image boundaries, and the **u8 is image-local** — never persist it, never compare it against a value another image produced.

Scope — a bridge image must not use these macros

A bridge image (Executor::open_multi) links two backends and therefore has no single answer, so neither macro means anything there; such an image asks per session instead, with nros_node_get_serialization_format(). scripts/check-format-macro-scope.py refuses a bridge-linked translation unit that references either macro.

Copyright 2026 nros contributors Licensed under Apache-2.0

Macro Definition Documentation

◆ NROS_ASSERT_MESSAGE_FORMAT

#define NROS_ASSERT_MESSAGE_FORMAT (   msg_format_id,
  type_literal 
)
Value:
"RFC-0088: " type_literal \
" is not encoded in the format the linked backend speaks " \
"(NROS_SERIALIZATION_FORMAT) — one image, one backend, one encoding")
#define NROS_SERIALIZATION_FORMAT_ID
Definition nros_generated.h:119
#define NROS_STATIC_ASSERT(cond, msg)
Definition serialization_format.h:71

Cross-image identity of NROS_SERIALIZATION_FORMAT_ID (RFC-0088 D2).

Derived from the discriminant rather than emitted beside it: cbindgen maps no Rust &str to a C constant, so a second generated macro would be a second authored spelling with nothing tying the two together. One generated number and one table is the shape that cannot drift into disagreeing with itself. Assert that a message type's serialization format is the one the linked backend speaks. Emitted once per generated message header.

Parameters
msg_format_idthe type's own NROS_MSG_FORMAT_ID_<type> macro
type_literalthe type's name, as a string literal, so the diagnostic names the message rather than the header

◆ NROS_SERIALIZATION_FORMAT_ID_CDR

#define NROS_SERIALIZATION_FORMAT_ID_CDR   1

◆ NROS_SERIALIZATION_FORMAT_ID_UORB

#define NROS_SERIALIZATION_FORMAT_ID_UORB   2

◆ NROS_STATIC_ASSERT

#define NROS_STATIC_ASSERT (   cond,
  msg 
)
Value:
typedef char NROS_STATIC_ASSERT_CAT(nros_static_assert_, \
NROS_STATIC_ASSERT_TAG_)[(cond) ? 1 : -1]
#define NROS_STATIC_ASSERT_TAG_
Definition serialization_format.h:69
#define NROS_STATIC_ASSERT_CAT(a, b)
Definition serialization_format.h:65

◆ NROS_STATIC_ASSERT_CAT

#define NROS_STATIC_ASSERT_CAT (   a,
 
)    NROS_STATIC_ASSERT_CAT_(a, b)

◆ NROS_STATIC_ASSERT_CAT_

#define NROS_STATIC_ASSERT_CAT_ (   a,
 
)    a##b

Portable compile-time assertion.

Spelled once here because the generated message headers are compiled as C and included from C++ (they carry their own extern "C" block), and _Static_assert is not a C++ keyword. C23 spells the C keyword static_assert too; C11 spells it _Static_assert; the C99 fallback is the negative-array-size idiom, so a freestanding pre-C11 toolchain still gets the diagnostic rather than silently skipping the check.

◆ NROS_STATIC_ASSERT_TAG_

#define NROS_STATIC_ASSERT_TAG_   __LINE__