Compile error: 'strcpy' was not declared in this scope - Why?

Hey!

While I am trying to fix some older code, which runs totally fine on the R3, for the R4 Wifi, I stumbled upon the following compile time message and I must admit, I absolutely don't understand why that happens:

In file included from lib/MenuManager/MenuManager.cpp:2:0:
lib/MenuManager/MenuManager.cpp: In member function 'char* MenuManager::getParentItemName(char*)':
/Users/me/.platformio/packages/framework-arduinorenesas-uno/cores/arduino/api/deprecated-avr-comp/avr/pgmspace.h:63:29: error: 'strcpy' was not declared in this scope
 #define strcpy_P(dest, src) strcpy((dest), (src))
                             ^
lib/MenuManager/MenuManager.cpp:33:5: note: in expansion of macro 'strcpy_P'
     strcpy_P(buf, (char *)pgm_read_word(&(msi->menu[msi->itemIndexPos].name)));
     ^~~~~~~~
/Users/me/.platformio/packages/framework-arduinorenesas-uno/cores/arduino/api/deprecated-avr-comp/avr/pgmspace.h:63:29: note: suggested alternative: 'strcpy_P'
 #define strcpy_P(dest, src) strcpy((dest), (src))
                             ^
lib/MenuManager/MenuManager.cpp:33:5: note: in expansion of macro 'strcpy_P'
     strcpy_P(buf, (char *)pgm_read_word(&(msi->menu[msi->itemIndexPos].name)));

This error might be totally fine and I have to fix it, but I'd like to understand what is happening here. Especially because the pgmspace.h file exists below the Renesas Core and references strcpy itself. And I thought, strcpy is a standard function, so how can this be missing at all?

Maybe someone can help with an explanation of what's going on.

Thanks,
Holger

Hi @hpandel. strcpy is declared in the standard library's string.h header. This header is #included by the Arduino core's Arduino.h file in addition to the api/deprecated-avr-comp/avr/pgmspace.h.

An #include directive for Arduino.h is automatically added to the .ino sketch file, so we are able to use strcpy_P and strcpy in that translation unit without any difficulty. However, the Arduino build system does not add any #include directives to non-.ino files so the developer has complete control over the #include directives used there. It probably would have been best for the Arduino core developers to add #include directives for all the dependencies of the file into api/deprecated-avr-comp/avr/pgmspace.h itself rather than relying on their prior existence externally (as is done in Arduino.h), but they didn't do that so it is necessary for the library developer to do so.

So the solution will be to add an #include <string.h> directive to MenuManager.cpp (or transitively via a header file #included by that file) above the #include directive for api/deprecated-avr-comp/avr/pgmspace.h (or whatever header file is #includeing that file transitively).

For example:

#include <string.h>
#include <api/deprecated-avr-comp/avr/pgmspace.h>

Hey @ptillisch ! Many many thanks for the explanation. So my thoughts went into the right direction but I could not imagine that the core developers of pgmspace.h might have left out some #include directives.

I can fix this easily myself. But if that happens again, I now know what's going on in this special case and that's great.

BTW, I also had to re-add strlcpy because pgmspace.h was referring to it, but it was nowhere defined. Annoying little inconsistencies R3 vs. R4...

Many thanks again,
Holger

You are welcome. I'm glad if I was able to be of assistance.

Regards,
Per