-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Description
Describe the bug
A clear and concise description of what the bug is.
What have you tried to diagnose or workaround this issue?
Shell is not compatible with C++.
To Reproduce
Steps to reproduce the behavior:
- Enable C++ and Shell at the prj file;
- Add code to initialize some shell command using the Shell Macros;
- mkdir build; cd build
- cmake -DBOARD=nucleo_f091rc -GNinja ..
- ninja
- See error
Expected behavior
A clear and concise description of what you expected to happen.
It must be possible to compile and execute the shell properly with C++.
Impact
What impact does this issue have on your progress (e.g., annoyance, showstopper)
The code does not compile, so the user would not use the shell on the firmware. Shell is an important feature for testing, interact and updating the code via mcumgr shell backend.
Screenshots or console output
If applicable, add a screenshot (drag-and-drop an image), or console logs
(cut-and-paste text and put a code fence (```) before and after, to help
explain the issue.
Here is the compilation log:
../src/main.cpp
In file included from ../src/main.cpp:22:0:
/home/r...t/zephyr/include/shell/shell.h:170:41: error: uninitialized const ‘shell_sub_h’ [-fpermissive]
static const struct shell_static_entry shell_##name[]; \
^
../src/main.cpp:104:1: note: in expansion of macro ‘SHELL_CREATE_STATIC_SUBCMD_SET’
SHELL_CREATE_STATIC_SUBCMD_SET(sub_h)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/r...t/zephyr/include/shell/shell.h:107:8: note: ‘const struct shell_static_entry’ has no user-provided default constructor
struct shell_static_entry {
^~~~~~~~~~~~~~~~~~
/home/r...t/zephyr/include/shell/shell.h:108:14: note: and the implicitly-defined constructor does not initialize ‘const char* shell_static_entry::syntax’
const char *syntax; /*!< Command syntax strings. */
^~~~~~
/home/r...t/zephyr/include/shell/shell.h:170:54: error: storage size of ‘shell_sub_h’ isn’t known
static const struct shell_static_entry shell_##name[]; \
^
../src/main.cpp:104:1: note: in expansion of macro ‘SHELL_CREATE_STATIC_SUBCMD_SET’
SHELL_CREATE_STATIC_SUBCMD_SET(sub_h)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/r...t/zephyr/include/shell/shell.h:172:12: error: expected primary-expression before ‘.’ token
.u.entry = \
^
../src/main.cpp:104:1: note: in expansion of macro ‘SHELL_CREATE_STATIC_SUBCMD_SET’
SHELL_CREATE_STATIC_SUBCMD_SET(sub_h)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/r...t/zephyr/include/shell/shell.h:82:2: error: taking address of temporary [-fpermissive]
}
^
/home/r...t/zephyr/include/shell/shell.h:213:52: note: in expansion of macro ‘SHELL_ARG’
.args = _mandatory ? (&(struct shell_static_args)SHELL_ARG( \
^~~~~~~~~
/home/r...t/zephyr/include/shell/shell.h:227:2: note: in expansion of macro ‘SHELL_CMD_ARG’
SHELL_CMD_ARG(_syntax, _subcmd, _help, _handler, 0, 0)
^~~~~~~~~~~~~
../src/main.cpp:106:5: note: in expansion of macro ‘SHELL_CMD’
SHELL_CMD(t, NULL, "APP Power on self test status", shell_app_post),
^~~~~~~~~
../src/main.cpp:104:32: warning: ‘sub_h’ defined but not used [-Wunused-variable]
SHELL_CREATE_STATIC_SUBCMD_SET(sub_h)
^
/home/r...t/zephyr/include/shell/shell.h:171:38: note: in definition of macro ‘SHELL_CREATE_STATIC_SUBCMD_SET’
static const struct shell_cmd_entry name = { .is_dynamic = false, \
^~~~
cc1plus: warning: unrecognized command line option ‘-Wno-register’
ninja: build stopped: subcommand failed.
Environment (please complete the following information):
- OS: Linux Ubuntu 18.04.1 LTS
- Toolchain Zephyr SDK 0.9.5
- Zephyr Version: zephyr-v1.13.0-4557-g2e68bc02b9
- git SHA: 2e68bc0
Additional context
The main issues I had to resolve was:
- ... error: uninitialized const ...
- ... error: expected primary-expression before ‘.’ token .u.entry ...
- ... error: taking address of temporary ...
- ... note: ‘const struct shell_static_entry’ has no user-provided default constructor ...
I could get the code running by changing the initialization approach on the shell macros, but I had to change the way to do, so here is the current solution:
#include <misc/printk.h>
#include <shell/shell.h>
#include <shell/shell_fprintf.h>
#include <stdio.h>
/**
* @brief Initializes a shell command arguments
*
* @param[in] _mandatory Number of mandatory arguments.
* @param[in] _optional Number of optional arguments.
*/
#define XXSHELL_ARG(_mandatory, _optional) \
{ \
_mandatory, _optional, \
}
#define XXSHELL_CMD_ARG(_syntax, _subcmd, _help, _handler, _mandatory, _optional) \
{ \
(const char *) STRINGIFY(_syntax), (const char *) _help, _subcmd, _handler, \
{ \
_mandatory, _optional \
} \
}
/**
* @brief Macro for creating a subcommand set. It must be used outside of any
* function body.
*
* @param[in] name Name of the subcommand set.
*/
#define XXSHELL_CREATE_STATIC_SUBCMD_SET(name, ...) \
static const struct shell_static_entry shell_##name[] = {__VA_ARGS__, \
SHELL_SUBCMD_SET_END}; \
static const struct shell_cmd_entry name = {false, \
{(shell_dynamic_get) shell_##name}};
/**
* @brief Initializes a shell command.
*
* @param[in] _syntax Command syntax (for example: history).
* @param[in] _subcmd Pointer to a subcommands array.
* @param[in] _help Pointer to a command help string.
* @param[in] _handler Pointer to a function handler.
*/
#define XXSHELL_CMD(_syntax, _subcmd, _help, _handler) \
{ \
(const char *) STRINGIFY(_syntax), (const char *) _help, _subcmd, _handler, NULL \
}
/**
* @brief Macro for defining and adding a root command (level 0) with
* arguments.
*
* @note All root commands must have different name.
*
* @param[in] syntax Command syntax (for example: history).
* @param[in] subcmd Pointer to a subcommands array.
* @param[in] help Pointer to a command help string.
* @param[in] handler Pointer to a function handler.
*/
#define XXSHELL_CMD_REGISTER(syntax, subcmd, help, handler) \
static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
XXSHELL_CMD(syntax, subcmd, help, handler); \
static const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax) \
__attribute__((section("." STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax))))) \
__attribute__((used)) = {false, \
{(shell_dynamic_get) &UTIL_CAT(_shell_, syntax)}}
int shell_app_post(const struct shell *shell, size_t argc, char **argv)
{
shell_print(shell, "post");
return 0;
}
int shell_app_reboot(const struct shell *shell, size_t argc, char **argv)
{
shell_print(shell, "reboot");
return 0;
}
XXSHELL_CREATE_STATIC_SUBCMD_SET(sub_h,
XXSHELL_CMD(t, NULL, "APP Power on self test status",
shell_app_post));
int main(void)
{
XXSHELL_CMD_REGISTER(h, &sub_h, "Info commands", NULL);
XXSHELL_CMD_REGISTER(r, NULL, "General reset commands", shell_app_reboot);
while (1) {
k_sleep(K_SECONDS(10));
printk("ping\n");
}
return 0;
}Code edited to avoid the warning: missing braces around initializer when compiling it in C.