Skip to content

The strnlen() C Function Is Not Available #18

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

Closed
woolseyj opened this issue Jun 30, 2023 · 9 comments · Fixed by #87
Closed

The strnlen() C Function Is Not Available #18

woolseyj opened this issue Jun 30, 2023 · 9 comments · Fixed by #87
Labels
conclusion: resolved Issue was resolved topic: code Related to content of the project itself type: imperfection Perceived defect in any part of project

Comments

@woolseyj
Copy link

It appears that several C functions, e.g. strnlen() and strdup(), defined in the AVR based cores are not available within the Renesas core.

Both of the following statements work on an Arduino Uno WiFi Rev2 board but the second statement does not work on the new Arduino Uno R4 WiFi board.

Serial.print("strlen = ");  Serial.println(strlen(string));
Serial.print("strnlen = ");  Serial.println(strnlen(string, 10));  // error: 'strnlen' was not declared in this scope

I came across this issue by trying to compile a sketch that uses the PubSubClient library.

Please see The strnlen() C Function Is Not Available topic within the Arduino Forum for more information.

@WestfW
Copy link

WestfW commented Aug 3, 2023

It looks like this is because the compile command line includes -D_XOPEN_SOURCE, which as I understand it causes quite an old set of API standards to be defined by the gcc include file structure...

There is a standard string.h with
size_t _EXFUN(strnlen,(const char *, size_t));

Hmm. It's inside conditionals:

#if __POSIX_VISIBLE >= 200809
size_t _EXFUN(strnlen,(const char *, size_t));
#endif
Alas, tracing why __POSIX_VISIBLE gets set to a particular value seems to be a non-trivial task (or at least requires tool knowledge that I don't have.)
SAMD compiles, which theoretically use the same toolchain, work fine.
(and indeed, R4 compiles have #define __POSIX_VISIBLE 199209, while SAMD has 200809)

Ahh. A bit of brute force says that __POSIX_VISIBLE gets set based on _POSIX_C_SOURCE, which defaults to 200809 unless _XOPEN_SOURCE is set less than 700. (in sys/features.h)

For some reason, the R4 build line includes a -D_XOPEN_SOURCE (SAMD doesn't define it at all.)

I don't know if that's intentional, or if someone thought that it means "Open Source" in the sense of OSSW. (I dont think that that's what it means!) (I can't find anything in the Arduino R4 core, the Arduino-api core, or the Renesas fsp code, that actually references _XOPEN_SOURCE

This does imply that the problem is in the #include files, and the function is actually present in the C library that is linked in. So a workaround is simply to provide an explicit prototype like:

extern "C" size_t _EXFUN(strnlen,(const char *, size_t));

facchinm added a commit to facchinm/ArduinoCore-renesas that referenced this issue Aug 4, 2023
The definition is needed by time.h (see arduino-libraries/MKRGSM@019b0e1) but we missed to give it a proper value :|

Defining to 700 is ok for POSIX 2017, so strnlen prototype gets picked up

Fixes arduino#18
@facchinm
Copy link
Member

facchinm commented Aug 4, 2023

@woolseyj @WestfW this should be tackled by #87

@per1234 per1234 added type: imperfection Perceived defect in any part of project topic: code Related to content of the project itself labels Aug 5, 2023
@aentinger
Copy link
Contributor

@woolseyj or @WestfW ☕ 👋

Can you confirm this change works for you?

@woolseyj
Copy link
Author

woolseyj commented Aug 8, 2023

@aentinger, I updated the platform.txt file with the -D_XOPEN_SOURCE=700 options and successfully tested my sketch using the PubSubClient library.

@aentinger
Copy link
Contributor

Hi @woolseyj ☕ 👋 thank you for taking the time to confirm this, I'll proceed with merging #87 .

@per1234 per1234 added the conclusion: resolved Issue was resolved label Aug 9, 2023
@woolseyj
Copy link
Author

woolseyj commented Sep 8, 2023

Confirmed to be working in production 1.0.4 tag.

@jimemo
Copy link

jimemo commented Sep 19, 2023

Confirmed to be working in production 1.0.4 tag.

@woolseyj thank you for tracking this down to resolution. I am still having the 'strnlen' was not declared in this scope; did you mean 'strlen'? errors when using the pubsubclient library. I'm wondering if I need to force a new version of renesas-ra ? I've created a new project (which I thought would install the latest renesas-ra). I also tried adding this to my platform.ini in platformio.

build_flags = 
    -D_XOPEN_SOURCE=700

Are there any additional steps that I need?

@Fashion-Corp
Copy link

Fashion-Corp commented Sep 19, 2023 via email

@per1234
Copy link
Collaborator

per1234 commented Sep 19, 2023

Hi all. Discussion of fixing the problem in PlatformIO is off topic here. You are welcome to continue the discussion in an appropriate channel such as Arduino Forum or the PlatformIO forum

@arduino arduino locked as resolved and limited conversation to collaborators Sep 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
conclusion: resolved Issue was resolved topic: code Related to content of the project itself type: imperfection Perceived defect in any part of project
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants