-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
device.h: C++20 compatibility #70403
Conversation
include/zephyr/device.h
Outdated
* 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please avoid referring to PRs in documentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I usually do avoid this but this issue is really complex (even when the corresponding code is not) and that PR discussion is quite important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PRs content is not part of Zephyr git history. Who knows if Github will stay Zephyr's VCS provider forever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm with Gerard on this, just refer to the commit, one can find back the PR out of band but really the commit should have enough context regardless
If you really want to link a PR maybe you can do it on this comment using the Link:
tag and the full URL?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who knows if Github will stay Zephyr's VCS provider forever.
I'm aware and I always try to avoid references to PRs when the git history is enough. But I think there can be some exceptions. It's not because something may disappear one day that it should not be referenced. If Zephyr migrates away from Github one day, then it should definitely export all past review discussions and migrate or archive them somewhere and then PR numbers would still be useful. I've been performing such archeology in the past and any reference helps.
Of course documentation is even better but (1) it's not mutually exclusive (2) not obvious where in the docs this obscure issue belongs (3) more "overhead" :-)
PRs content is not part of Zephyr git history.
True but the git history does not exist in a complete vacuum either.
If you really want to link a PR maybe you can do it on this comment using the Link: tag and the full URL?
That would work for me.
Or I can just delete the PR number entirely if it's really important for you. I think that would be a loss but it's not that big of a deal for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Full link of external references in the commit I think are fine, Linux does it as well, it's more my opinion than a general rule but I think it's a good idea and I occasionally do it myself too.
include/zephyr/device.h
Outdated
} | ||
|
||
/* | ||
* Anonymous unions require C11. Some pre-C11 gcc versions have early |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is repeating information, can’t it be put somewhere and reference it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to summarize it but I agree it's still a bit long and duplicated... any suggestion of a good place? I couldn't think of a really better way to document this sorry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe Zephyr coding guidelines? It looks like we'll need to apply this in other places if we want C++20 compatibility. An explanation there, plus a code snippet would be a solution, you could then just say "Refer to doc/xxx.rst"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'll take a look in the next couple weeks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx for the review! Answers below.
include/zephyr/device.h
Outdated
} | ||
|
||
/* | ||
* Anonymous unions require C11. Some pre-C11 gcc versions have early |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to summarize it but I agree it's still a bit long and duplicated... any suggestion of a good place? I couldn't think of a really better way to document this sorry.
include/zephyr/device.h
Outdated
* 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I usually do avoid this but this issue is really complex (even when the corresponding code is not) and that PR discussion is quite important.
a19094b
to
db0326e
Compare
Tentative v3.7.0 milestone because this PR is:
Absolutely zero feature change. |
@gmarull please review |
# 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) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Odd to find this macro defined after it was "used" above. Not strictly required, of course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This places the macro closer to the two locations where it's used.
It's also a lower-level implementation detail, so I think it it reads better last - that's subjective of course.
EDIT: I wrote too fast, I was referring to Z_DEVICE_INIT_ENTRY_DEV()
. Then I wanted to preserve the "top-down" order for the next macro.
I think it's "odd" only if you're tainted by C compilation which requires "forward" declarations. Maybe dating all the way back to when compilation was performed in a single pass? Funny how the pre-processor is in some respect more advanced that C itself... https://stackoverflow.com/questions/3136686/is-the-c99-preprocessor-turing-complete
include/zephyr/device.h
Outdated
* 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_),}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this missing a trailing ,
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see #74970
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch, thank you @gmarull for the fix in #74970. Note this regression is only 3 weeks old and independent of this PR. My bad though for not noticing it when I rebased on top of it.
So I just:
- rebased on top of your comma fix device: only define/initialize metadata for DT devices #74970
- Added
CONFIG_DEVICE_DT_METADATA
to theprj.conf
, on top of the other additions that were already in this PR. I checked it would have caught this bug.
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 <[email protected]>
This provides C++ build test coverage for device.h (notably: Z_DEVICE_INIT() fixed in the previous commit) and for some other Device Tree macros. Signed-off-by: Marc Herbert <[email protected]>
Fixes the following error appearing in the test coverage added by the next commit: In file included from zephyr/tests/lib/cpp/cxx/src/main.cpp:18: ``` zephyr/include/zephyr/pm/device.h:275:9: error: designator order for field 'pm_device_base::state' does not match declaration order in 'pm_device_base' 275 | } | ^ zephyr/include/zephyr/pm/device.h:315:17: note: in expansion of macro 'Z_PM_DEVICE_INIT' 315 | Z_PM_DEVICE_INIT(Z_PM_DEVICE_NAME(dev_id), node_id, ``` Note this failure is observed with any g++ -std=c++NN standard value - even before C++20. Signed-off-by: Marc Herbert <[email protected]>
Note CONFIG_PM_* affects device.h too. Even if not compiled, the more code the pre-processor sees the better. Signed-off-by: Marc Herbert <[email protected]>
efa14ae
This option allows you to look up a struct device from any of the node labels that were attached to the devicetree node used to create the device, etc. This is helpful because node labels are a much more human-friendly set of unique identifiers than the node names we are currently relying on for use with device_get_binding(). Adding this infrastructure in the device core allows anyone to make use of it without having to replicate node label storage and search functions in various places in the tree. The main use case, however, is for looking up devices by node label in the shell. Since there is a footprint penalty associated with storing the node label metadata, leave this option disabled by default. Signed-off-by: Martí Bolívar <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just force-pushed:
- Rebased on top of comma fix device: only define/initialize metadata for DT devices #74970 fixing 3 weeks old regression from Allow specifying devices by DT node label in the shell #71912
- Added
CONFIG_DEVICE_DT_METADATA
to theprj.conf
, on top of the other CONFIG_ additions that were already in this PR. It would have caught this "foreign" regression.
NO OTHER CHANGE.
Please re-review this very minor update quickly before I have to rebase on top of another regression and then another fix :-)
Sorry for the inconvenience.
# 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) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This places the macro closer to the two locations where it's used.
It's also a lower-level implementation detail, so I think it it reads better last - that's subjective of course.
EDIT: I wrote too fast, I was referring to Z_DEVICE_INIT_ENTRY_DEV()
. Then I wanted to preserve the "top-down" order for the next macro.
I think it's "odd" only if you're tainted by C compilation which requires "forward" declarations. Maybe dating all the way back to when compilation was performed in a single pass? Funny how the pre-processor is in some respect more advanced that C itself... https://stackoverflow.com/questions/3136686/is-the-c99-preprocessor-turing-complete
include/zephyr/device.h
Outdated
* 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_),}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch, thank you @gmarull for the fix in #74970. Note this regression is only 3 weeks old and independent of this PR. My bad though for not noticing it when I rebased on top of it.
So I just:
- rebased on top of your comma fix device: only define/initialize metadata for DT devices #74970
- Added
CONFIG_DEVICE_DT_METADATA
to theprj.conf
, on top of the other additions that were already in this PR. I checked it would have caught this bug.
Could I get just one of the previous approvers to take another, quick look? Thanks in advance! |
2 fixes + 2 corresponding
tests/
commits, please check commit messages.Apply to device.h and pm/device.h the C/C++ compatibility lessons learned for init.h in #69411