-
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
Define _POSIX_C_SOURCE in a few files which use strnlen() #68233
Conversation
This reverts commit 07943ea. As newlib does not expose by default strnlen(), we still need to set this macro in general, otherwise we will get an "implicit declaration" warning when building for newlib or other C libraries which do not expose it. Let's set it to 200809L instead of 200809 and let's undefine it first to be sure we do not get a redefinition warning. Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
Thanks. @aescolar @cfriedt @keith-packard, I suggested this removal during POSIX discussions, but as you see, newlib requires it and I missed it. Is there any better solution for this scenario besides forcing this in the source file? |
There is an ongoing discussion about having Newlib set it, #67040 (comment) , or change its integration so it exposes this funcion by default but that has consecuences, so it won't happen right away. |
How about https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/wifi/eswifi/eswifi_core.c#L493 (not that this file was touched in the reverted commit, but I'd guess it's impacted too?) |
And actually, how about the handful of other files in tree that use strnlen and don't have the macro set? ex. |
@kartben I guess they were not normally being built before with newlib, and are not built either now. So nobody has realized or realizes yet about it. We default to picolibc, so this issues will be quite hidden. I only realized about this particular case because of your report in the other PR. |
As newlib does not expose by default strnlen(), we need to set this macro, otherwise we will get an "implicit declaration" warning when building for newlib or other C libraries which do not expose it. Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
As newlib does not expose by default strnlen(), we need to set this macro, otherwise we will get an "implicit declaration" warning when building for newlib or other C libraries which do not expose it. Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
As newlib does not expose by default strnlen(), we need to set this macro, otherwise we will get an "implicit declaration" warning when building for newlib or other C libraries which do not expose it. Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
a74922e
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.
Personally, I think we should be using the ISO C standard variant of strnlen()
(namely strnlen_s()
) where POSIX is not intended to be used. It's likely available in all libcs except maybe the minimal one, but adding it there is a trivial change.
https://en.cppreference.com/w/c/string/byte/strlen
strnlen_s()
is a drop-in replacement for strnlen()
.
There would be one less special case to consider in terms of coding guidelines, as a bonus.
|
I was looking for this section in the coding guidelines but had some difficulty finding it
In that case, I guess it doesn't make sense to hold off for a potentially lengthy RFC process. However, I do think that we should prefer sticking to ISO C rather than forcing POSIX APIs to be exposed in various places where it should not be (according to A.4 and A.5). |
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.
Not going to hold this up, but I do think we should use the ISO C variant (strnlen_s()
) instead of forcing the entire POSIX API to be exposed when it isn't necessary or desired.
This change seems to move in the direction of not asking that the C library express the full Zephyr API by default, and effectively requiring any file using POSIX apis to add the |
I could find this #57598 (comment) |
I'm confused then -- either the default Zephyr C Library API includes
Exactly. We have two choices here:
I had thought the directly from the TSC was clear -- Zephyr defines its own C library API and applications that limit themselves to that API need not define any
Not in any standards-conforming fashion though; Annex K doesn't allow for subsetting, so the library would need to set
Probably because few (if any) C library implementations have adopted this part of the spec. It's a pretty big lift as well; a huge part of the library ends up with two parallel implementations. https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm has a pretty good explanation of how Annex K has failed to see any significant adoption. In the case of strnlen, it would have been far better for the ISO C committee to simply include that function in the spec, rather than creating a new name for the POSIX function with, what appears to be, identical semantics. Essentially, if you want to provide |
I don't think it's the overall plan, at least, not according to the coding guidelines. Strnlen is probably a special case because it's one of the non-ISO-C / POSIX APIs that Zephyr has chosen to support. We can easily support The following paragraph (from rule A.5 seems to articulate the same point I was trying to make earlier.
Maybe @stephanosio could shed some light. Personally, I think using the standard There might be some unintentional overuse of the term "standard" in the quoted paragraph above (maybe it should read "common C libraries"?). |
In this particular case, I'd argue pretty strenuously that using
No, I think "standard" is the right term. Any API which is not part of a commonly implemented de jure standard should be looked at with a wary eye. We're looking for well-defined and well-supported interfaces here. POSIX is definitely a good source for interfaces of this kind; managed by a respected standards body (IEEE) and broadly implemented across numerous systems (Linux, BSD, Windows). Annex K fails this test as it has not only no usable implementations (even the Windows C library is non-conforming), it has been intentionally excluded from several (including Glibc). |
Correct. And I am well aware of that 😁. I was using the definition of "non-standard" per the coding guidelines (below).
In any case, we can also move strnlen to lib/libc/common or lib/posix, and make that function visible when either _POSOX_C_SOURCE or _ZEPHYR_SOURCE is defined.
Cool - let's put it in lib/lib/common and guard the declaration with _POSIX_C_SOURCE or _ZEPHYR_SOURCE. Problem solved 😃 No unnecessary definitions of _POSIX_C_SOURCE required. In fact, we don't even need to move the implementation, all we need to do is declare 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.
Temporary nak until a better solution is available.
Yeah, we don't want to replace any C library implementation with something from libc/common -- the C library may well have a nice optimized version (as newlib and picolibc do for aarch64). However, it needs to be declared in Oh. Maybe this kludge should go into the newlib support bits -- have that provide a (the same should go for |
@keith-packard - you are a mind reader! 😅 |
@keith-packard , @cfriedt , @kartben As a short answer, this PR just tries to ensure this files build well with newlib (or other libCs) without the issue of defining globally |
Ya, and to, I think, an earlier point of yours, I think this should go in as a (hot)fix for now, since it can break for users, until better/other solutions are explored. |
I did, originally, until it was mentioned that this PR should set some sort of precedent making blanket use if _POSIX_C_SOURCE OK, which I think is definitely not any kind of conclusion that should be extrapolated from this. Unfortunately, I would have to say that #68261 is still technically a better solution and there have not been any compelling arguments otherwise. |
I've rewritten #67040 so that newlib now provides the Zephyr API, including |
While All that aside, the adoption rate of the From N2336:
Based on the above, I would argue that, for all practical purposes, |
Thanks for clarifying @stephanosio . Keith's solution in #68381 works for me in terms of newlib |
Replaying to #68233 (comment) , @keith-packard
Note that there is no such dichotomy. There is other C libraries beyond the default C library (Pico) or beyond other libraries for which Zephyr may provide extra support for. |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
Define _POSIX_C_SOURCE in a few files which use strnlen()
As newlib does not expose by default strnlen(), we need to set this macro, otherwise we will get an
"implicit declaration" warning when building for newlib or other C libraries which do not expose it.
These cases were missed from #67052 as they were not triggered by CI as we do not build by default with newlibc.