-
Notifications
You must be signed in to change notification settings - Fork 3
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
Add C++ version check to char16 definition #3
Conversation
@methylDragon could you take a look? This is required for the upcoming micro-ROS Iron release. Thanks a lot. |
@@ -26,7 +26,7 @@ extern "C" { | |||
# define INCLUDED_UCHAR 1 | |||
# endif | |||
#endif | |||
#if !defined(INCLUDED_UCHAR) | |||
#if !defined(INCLUDED_UCHAR) && __cplusplus <= 199711L |
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 will only compile if __cplusplus
is defined, no?
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 guess that we shall also add a check on defined(__cplusplus). Can you take a look @Acuadros95?
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.
Undefined values on macros are replaced with a 0
value. So if __cplusplus
is not defined this condition will always be true: __cplusplus <= 199711L
.
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.
As @clalancette mentioned, this does not make sense. We use C++14/C++17 with gcc and msvc and this compiles fine. According to the standard, this type is defined only when <uchar.h>
is included:
https://en.cppreference.com/w/c/string/multibyte/char16_t
Since this header is not available on some machines, e.g. macOS and Cygwin, we added this bit of code. I think we need some checks to avoid making this type def in more cases (like yours), but it's not because of the C++ version. It likely has to do with the std library you are using in microROS and that is defines this type (char16_t
) in a different header that is being included automatically here, e.g. maybe via stdint.h
or something else in the .c
file that's failing to compile.
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.
We use C++14/C++17 with gcc and msvc and this compiles fine. According to the standard, this type is defined only when <uchar.h> is included:
That is for C, for C++11 and beyond its a keyword and cannot be redefined:
https://en.cppreference.com/w/cpp/keyword/char16_t
I guess the problem is that our compiler does not have the __has_include
definition, and the <uchar.h>
header is most probably checking the used C++ version to add the typedef or not, example:
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 guess the problem is that our compiler does not have the
__has_include
definition, and the<uchar.h>
header is most probably checking the used C++ version to add the typedef or not, example:
I see. That makes a whole lot more sense. Thanks. In that case, then I think we should probably rewrite this whole section (including the stuff above) to something like:
#if defined(__cplusplus) && __cplusplus >= 201103L
// Nothing to do here, C++11 and beyond have char16_t as a keyword:
// https://en.cppreference.com/w/cpp/keyword/char16_t
#elif defined(__has_include) && __has_include(<uchar.h>)
// If the compiler has __has_include, and uchar.h exists, include that as it will have char16_t
// as a typedef.
# include <uchar.h>
#else
// Otherwise assume that char16_t isn't defined anywhere, and define it ourselves as uint_least16_t.
# include <stdint.h>
typedef uint_least16_t char16_t;
#endif
That is, if we are on C++11 or newer, just assume it is a keyword. If we aren't on C++, or it is too old, then try to use __has_include
to find the uchar.h
header and include that. If all of that fails, assume char16_t
isn't defined and define it ourselves. @pablogs9 @Acuadros95 can you give this a try and see if it works with your compiler?
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.
Sounds good. @Acuadros95 can you try 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.
@clalancette Just tested the new checks and can confirm it works.
I have updated the PR here ac34007
I'm actually a little confused about:
|
If it is ok to remove it, we are also ok.
As far as I have tested, in GCC 12 with C++17 this kind of override is an error unless you have Could you take a look at that @clalancette ? |
Sure, but the check that is already there seems to handle it. If you edit your example to put the current checks in place, it compiles fine: https://godbolt.org/z/zYG81csjr I also verified locally that I can build with gcc 12.2.1, and everything compiles fine here. So I still don't understand why your build is failing. |
I encounter the same error on MacOS with Apple Clang and can confirm that this PR fixes the build. |
Hello, @Yadunund are you using an ARM architecture? @clalancette here you have my local tests using ARM compiler: Ubuntu 20.04 + gcc-arm-none-eabi 9.2.1
Ubuntu 22.04 + gcc-arm-none-eabi 10.3.1
|
Ah yes forgot to mention i'm on arm64 (Apple Silicon) |
Any update on this? |
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 don't think this is the right check to make to avoid this typedef, though I can see how some other condition should be here to avoid this problem.
For comparison, on my macOS machine (arm64) @pablogs9's
|
Signed-off-by: acuadros95 <acuadros1995@gmail.com>
Signed-off-by: acuadros95 <acuadros1995@gmail.com>
@clalancette Can this PR be backported to Iron? |
@Mergifyio backport iron |
✅ Backports have been created
|
* Add C++ version condition to char16 definition Signed-off-by: acuadros95 <acuadros1995@gmail.com> (cherry picked from commit 0ab4827)
This definition is problematic for C++ compilers using C++11 or superior as
char16_t
becomes a builtin type, leading to the following error:This PR adds a check for C++ version used, avoiding the type definition for C++11 and upper versions.