+ * static struct mystruct *var = LTTNG_UST_COMPOUND_LITERAL(struct mystruct, { 1, 2, 3 });
+ */
+#if defined (__cplusplus) && defined (LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP)
+#define LTTNG_UST_COMPOUND_LITERAL(type, ...) new (type) __VA_ARGS__
+#else
+#define LTTNG_UST_COMPOUND_LITERAL(type, ...) (type[]) { __VA_ARGS__ }
+#endif
+
+/*
+ * Compile time assertion.
+ * - predicate: boolean expression to evaluate,
+ * - msg: string to print to the user on failure when `static_assert()` is
+ * supported,
+ * - c_identifier_msg: message to be included in the typedef to emulate a
+ * static assertion. This parameter must be a valid C identifier as it will
+ * be used as a typedef name.
+ */
+#ifdef __cplusplus
+#define lttng_ust_static_assert(predicate, msg, c_identifier_msg) \
+ static_assert(predicate, msg)
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+#define lttng_ust_static_assert(predicate, msg, c_identifier_msg) \
+ _Static_assert(predicate, msg)
+#else
+/*
+ * Evaluates the predicate and emit a compilation error on failure.
+ *
+ * If the predicate evaluates to true, this macro emits a function
+ * prototype with an argument type which is an array of size 0.
+ *
+ * If the predicate evaluates to false, this macro emits a function
+ * prototype with an argument type which is an array of negative size
+ * which is invalid in C and forces a compiler error. The
+ * c_identifier_msg parameter is used as the argument identifier so it
+ * is printed to the user when the error is reported.
+ */
+#define lttng_ust_static_assert(predicate, msg, c_identifier_msg) \
+ void lttng_ust_static_assert_proto(char c_identifier_msg[2*!!(predicate)-1])
+#endif
+
+/* Combine two tokens. */
+#define LTTNG_UST_COMPILER__COMBINE_TOKENS(_tokena, _tokenb) \
+ _tokena##_tokenb
+#define LTTNG_UST_COMPILER_COMBINE_TOKENS(_tokena, _tokenb) \
+ LTTNG_UST_COMPILER__COMBINE_TOKENS(_tokena, _tokenb)
+/*
+ * Wrap constructor and destructor functions to invoke them as functions with
+ * the constructor/destructor GNU C attributes, which ensures that those
+ * constructors/destructors are ordered before/after C++
+ * constructors/destructors.
+ *
+ * Wrap constructor and destructor functions as the constructor/destructor of a
+ * variable defined within an anonymous namespace when building as C++ with
+ * LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP defined. With this option,
+ * there are no guarantees that the events in C++ constructors/destructors will
+ * be traced.