Skip to content

Commit

Permalink
device.h: make it compatible with both C++20 and pre-C11 gcc
Browse files Browse the repository at this point in the history
Use braces conditionally for designated initializers of anonymous
unions. This is for device.h what what commit 19a33c7 ("init.h:
restore designated initializers in SYS_INIT_NAMED()") did for init.h

See long discussion in zephyrproject-rtos#69411 for more obscure C/C++ compatibility
details.

Signed-off-by: Marc Herbert <[email protected]>
  • Loading branch information
marc-hb committed Mar 19, 2024
1 parent 368e133 commit 186dee3
Showing 1 changed file with 33 additions and 5 deletions.
38 changes: 33 additions & 5 deletions include/zephyr/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -906,9 +906,24 @@ static inline bool z_impl_device_is_ready(const struct device *dev)
.state = (state_), \
.data = (data_), \
IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \
IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),})) /**/ \
Z_DEVICE_INIT_PM_BASE(pm_) \
}

/*
* 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. These braces are
* compatible with any C version but not with C++20. For more obscure
* C/C++ compatibility details see commit c15f029a7108 and PR #69411.
*/
#if defined(__STDC_VERSION__) && (__STDC_VERSION__) < 201100
# define Z_DEVICE_INIT_PM_BASE(pm_) \
IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),}))
#else
# define Z_DEVICE_INIT_PM_BASE(pm_) \
IF_ENABLED(CONFIG_PM_DEVICE, (.pm_base = (pm_),))
#endif

/**
* @brief Device section name (used for sorting purposes).
*
Expand Down Expand Up @@ -980,12 +995,25 @@ static inline bool z_impl_device_is_ready(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. These braces are
* compatible with any C version but not with C++20. For more obscure
* C/C++ compatibility details see commit c15f029a7108 and PR #69411.
*/
#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 186dee3

Please sign in to comment.