Skip to content

Commit

Permalink
device.h: conditionally remove init braces for C++20 compatibility
Browse files Browse the repository at this point in the history
Conditionally remove braces for designated initializers of anonymous
unions. This makes it compatible with C++20 while not breaking pre-C11
gcc.

This does for device.h what commit c15f029 ("init.h: restore
designated initializers in SYS_INIT_NAMED()") did for init.h

See https://docs.zephyrproject.org/latest/develop/languages/cpp/ and
long discussion in zephyrproject-rtos#69411 for more obscure C/C++ compatibility details.

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
  • Loading branch information
marc-hb authored and AlienSarlak committed Jul 13, 2024
1 parent a756386 commit d593995
Showing 1 changed file with 28 additions and 9 deletions.
37 changes: 28 additions & 9 deletions include/zephyr/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -1020,13 +1020,24 @@ device_get_dt_nodelabels(const struct device *dev)
.state = (state_), \
.data = (data_), \
IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \
IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),},)) /**/ \
IF_ENABLED(CONFIG_PM_DEVICE, Z_DEVICE_INIT_PM_BASE(pm_)) /**/ \
IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \
(IF_ENABLED(DT_NODE_EXISTS(node_id_), \
(.dt_meta = &Z_DEVICE_DT_METADATA_NAME_GET( \
dev_id_),)))) \
}

/*
* Anonymous unions require C11. Some pre-C11 gcc versions have early support for anonymous
* unions but they require these braces when combined with C99 designated initializers. For
* more details see https://docs.zephyrproject.org/latest/develop/languages/cpp/
*/
#if defined(__STDC_VERSION__) && (__STDC_VERSION__) < 201100
# define Z_DEVICE_INIT_PM_BASE(pm_) ({ .pm_base = (pm_),},)
#else
# define Z_DEVICE_INIT_PM_BASE(pm_) (.pm_base = (pm_),)
#endif

/**
* @brief Device section name (used for sorting purposes).
*
Expand Down Expand Up @@ -1098,10 +1109,7 @@ device_get_dt_nodelabels(const struct device *dev)
Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
.init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
(init_fn_)}, \
{ \
COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
&DEVICE_NAME_GET(dev_id), \
}, \
Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id), \
}

#define Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_) \
Expand All @@ -1110,12 +1118,23 @@ device_get_dt_nodelabels(const struct device *dev)
Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
.init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
(init_fn_)}, \
{ \
COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
&DEVICE_NAME_GET(dev_id), \
}, \
Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id), \
}

/*
* Anonymous unions require C11. Some pre-C11 gcc versions have early support for anonymous
* unions but they require these braces when combined with C99 designated initializers. For
* more details see https://docs.zephyrproject.org/latest/develop/languages/cpp/
*/
#if defined(__STDC_VERSION__) && (__STDC_VERSION__) < 201100
# define Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id) { Z_DEV_ENTRY_DEV(node_id, dev_id) }
#else
# define Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id) Z_DEV_ENTRY_DEV(node_id, dev_id)
#endif

#define Z_DEV_ENTRY_DEV(node_id, dev_id) \
COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = &DEVICE_NAME_GET(dev_id)

/**
* @brief Define a @ref device and all other required objects.
*
Expand Down

0 comments on commit d593995

Please sign in to comment.