-
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
address-of-temporary idiom not allowed in C++ #18551
Comments
This is a serious bug to the degree C++ is supposed to be usable for Zephyr applications. A fix may require a different API for C++. The priority should be based on the desire for supporting C++ use. |
CC @jhedberg |
I understand the problem, but I don't see how this is preventing C++ usage. C++ code could just declare a |
It doesn't prevent C++ usage, even with the same apparent application-level API that's used for C code, as in all the examples. It does mean that the definition of those macros, and the signature of The macros would have to expand to a temporary object, rather than the address of a temporary, and the globally visible |
@pabigot let me clarify: the
|
Agreed; the thing is that sample code uses that, and it's convenient for many cases, so it'd be nice if the same source worked in C++. That gets to the question of exactly what C++ support in Zephyr means. But it certainly can be done. I do not think that the solution is to remove the use of this idiom from Zephyr, but possibly to add look-alike C++ API alternatives to the header. |
@jhedberg |
@maksimmasalski I'm not sure what you mean. I don't really have anything further to add than what I've already commented in this issue. As it stands, there's nothing preventing C++ code from using the @pabigot said:
However I'm not familiar enough with C++ to say what the "look-alike" API alternative would be. |
Understood. Let's see how I can help you. If @pabigot can assist me with vision how C++ must be supported in Zephyr, it will be good first entry. |
The approach I've considered involves introducing material conditional on I don't think that approach should be selected until we've carefully considered other options, because it's not clean. As noted there is a workaround, so this isn't going to block anybody. This issue is really not a good candidate for an initial contribution as it involves developing new core language API. The need to solve this issue should inform efforts like #19315 which aim to support C++ application development more generally, and which may include creation of a more general solution.
|
For the record, there are several other macros with the Bluetooth API that use the same approach, e.g. |
As being said in the first comment, this is not exclusive to the Bluetooth stack -- json.h for example also has these macros: |
The worst "offender" of this is the If Bluetooth services are to be defined in C++ code I suspect we'll need a whole suite of parallel definitions to produce the declaration object hierarchies. The replace-pointer-with-reference approach in #18551 (comment) remains the best option I'm aware of so far, but it's far more invasive than I'd hoped. |
I recently discovered the same issue with some of the bt macros. It can be resolved (at least for gcc-8) by turning the inline struct initialiser into an array of [1] which prevents the compiler treating it as a temporary variable. For the example above this would look something like.
|
@daniel-james-sherwood Formatting fixed; thanks for the tip, that could be a very clean solution. |
Seems to work for me. For both const and non-const structs. Also doesn't appear to affect C builds. |
Agreed. It does expose a lot of implicit casts from @daniel-james-sherwood If you want to prepare a PR for this I'll defer to you; otherwise I'll go through and convert everything necessary to get all in-tree Bluetooth samples (and tests?) building with C++ sometime in the first part of v2.2 development. Thanks for suggesting this way forward. |
You go ahead. My changes are mixed up with some others adding this C++ bindings to various APIs. Note you seem to have added an extra const to your first change. |
I came across this issue due to a compilation error I'm getting, when I try to change one of Nordic's nRF Connect SDK examples from C to C++. In the
Apparently, after the fix provided for this issue, this is still an issue, but now in a slightly different way. Is this worth opening a new issue? Note: when I make the |
That workaround is described at #24829 (comment), but it is still not legal C++. There is no known standard-conforming way to make the C API work in C++. #24829 (comment) describes the general solution for this problem. |
This worked for me too. Same problem as reported by the OP. |
+1 for the |
Same here. |
Several places in Zephyr, particularly but not exclusively the Bluetooth stack, use an idiom of taking the address of a structure literal to pass complex configuration information into a function. Below is what is used to produce the
BT_LE_ADV_CONN
parameter passed tobt_le_adv_start()
to identify the type of advertisement:Taking the address of a temporary is an error when using C++: the correct idiom in that environment involves passing the temporary by reference. Allowing this idiom to be used requires
-fpermissive
, which is not a good solution.The text was updated successfully, but these errors were encountered: