next gcc problem: error: initializer element is not constant
Hi all, I'm trying to update bluez to 5.59 and run across these errors when building with Leap 15.2/3's gcc-7: tools/mesh-cfgtest.c:131:10: error: initializer element is not constant .path = cli_app_path, ^~~~~~~~~~~~ tools/mesh-cfgtest.c:131:10: note: (near initialization for 'client_app.path') tools/mesh-cfgtest.c:132:16: error: initializer element is not constant .agent_path = cli_agent_path, ^~~~~~~~~~~~~~ tools/mesh-cfgtest.c:132:16: note: (near initialization for 'client_app.agent_path') tools/mesh-cfgtest.c:140:12: error: initializer element is not constant .path = cli_ele_path_00, ^~~~~~~~~~~~~~~ This is the code in question: ---------------------------------------------------- static const char *dbus_err_args = "org.freedesktop.DBus.Error.InvalidArgs"; static const char *const cli_app_path = "/mesh/cfgtest/client"; static const char *const cli_agent_path = "/mesh/cfgtest/client/agent"; static const char *const cli_ele_path_00 = "/mesh/cfgtest/client/ele0"; static const char *const srv_app_path = "/mesh/cfgtest/server"; static const char *const srv_agent_path = "/mesh/cfgtest/server/agent"; static const char *const srv_ele_path_00 = "/mesh/cfgtest/server/ele0"; static const char *const srv_ele_path_01 = "/mesh/cfgtest/server/ele1"; static struct meshcfg_app client_app = { .path = cli_app_path, .agent_path = cli_agent_path, .cid = 0x05f1, .pid = 0x0002, .vid = 0x0001, .crpl = MAX_CRPL_SIZE, .num_ele = 1, .ele = { { .path = cli_ele_path_00, .index = PRIMARY_ELE_IDX, .mods = {CFG_SRV_MODEL, CFG_CLI_MODEL}, .vmods = {0xffffffff, 0xffffffff} } } }; ------------------------------------------------ for my untrained eye cli_app_path, cli_agent_path and cli_ele_path_00 look perfectly const. But what do I know? This code builds fine with gcc-8 or newer. Is there an easy fix for this code to compile with gcc-7, or is the way to go to use "BuildRequires: gcc8" and "export CC=gcc-8" on anything older than Factory? Thanks, -- Stefan Seyfried "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." -- Richard Feynman
Am 17.06.21 um 15:34 schrieb Stefan Seyfried:
I'm trying to update bluez to 5.59 and run across these errors when building with Leap 15.2/3's gcc-7:
tools/mesh-cfgtest.c:131:10: error: initializer element is not constant .path = cli_app_path, ^~~~~~~~~~~~ tools/mesh-cfgtest.c:131:10: note: (near initialization for 'client_app.path') tools/mesh-cfgtest.c:132:16: error: initializer element is not constant .agent_path = cli_agent_path, ^~~~~~~~~~~~~~ tools/mesh-cfgtest.c:132:16: note: (near initialization for 'client_app.agent_path') tools/mesh-cfgtest.c:140:12: error: initializer element is not constant .path = cli_ele_path_00, ^~~~~~~~~~~~~~~
This is the code in question: ---------------------------------------------------- static const char *dbus_err_args = "org.freedesktop.DBus.Error.InvalidArgs"; static const char *const cli_app_path = "/mesh/cfgtest/client"; static const char *const cli_agent_path = "/mesh/cfgtest/client/agent"; static const char *const cli_ele_path_00 = "/mesh/cfgtest/client/ele0"; static const char *const srv_app_path = "/mesh/cfgtest/server"; static const char *const srv_agent_path = "/mesh/cfgtest/server/agent"; static const char *const srv_ele_path_00 = "/mesh/cfgtest/server/ele0"; static const char *const srv_ele_path_01 = "/mesh/cfgtest/server/ele1";
static struct meshcfg_app client_app = { .path = cli_app_path, .agent_path = cli_agent_path, .cid = 0x05f1, .pid = 0x0002, .vid = 0x0001, .crpl = MAX_CRPL_SIZE, .num_ele = 1, .ele = { { .path = cli_ele_path_00, .index = PRIMARY_ELE_IDX, .mods = {CFG_SRV_MODEL, CFG_CLI_MODEL}, .vmods = {0xffffffff, 0xffffffff} } } }; ------------------------------------------------ for my untrained eye cli_app_path, cli_agent_path and cli_ele_path_00 look perfectly const. But what do I know?
Might be <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960>. GCC 7 only supports C11, and there it seems string literals are not considered constant expressions. (Comment 9 on the bug.) C is a lot more restrictive than C++ when it comes to that stuff, see e.g. <http://c-faq.com/ansi/constasconst.html>. Adding Richard and Martin because I have only passing knowledge of C. Best regards, Aaron
On Thu, 17 Jun 2021, Stefan Seyfried wrote:
Hi all,
I'm trying to update bluez to 5.59 and run across these errors when building with Leap 15.2/3's gcc-7:
tools/mesh-cfgtest.c:131:10: error: initializer element is not constant .path = cli_app_path, ^~~~~~~~~~~~ tools/mesh-cfgtest.c:131:10: note: (near initialization for 'client_app.path') tools/mesh-cfgtest.c:132:16: error: initializer element is not constant .agent_path = cli_agent_path, ^~~~~~~~~~~~~~ tools/mesh-cfgtest.c:132:16: note: (near initialization for 'client_app.agent_path') tools/mesh-cfgtest.c:140:12: error: initializer element is not constant .path = cli_ele_path_00, ^~~~~~~~~~~~~~~
This is the code in question: ---------------------------------------------------- static const char *dbus_err_args = "org.freedesktop.DBus.Error.InvalidArgs"; static const char *const cli_app_path = "/mesh/cfgtest/client"; static const char *const cli_agent_path = "/mesh/cfgtest/client/agent"; static const char *const cli_ele_path_00 = "/mesh/cfgtest/client/ele0"; static const char *const srv_app_path = "/mesh/cfgtest/server"; static const char *const srv_agent_path = "/mesh/cfgtest/server/agent"; static const char *const srv_ele_path_00 = "/mesh/cfgtest/server/ele0"; static const char *const srv_ele_path_01 = "/mesh/cfgtest/server/ele1";
static struct meshcfg_app client_app = { .path = cli_app_path, .agent_path = cli_agent_path, .cid = 0x05f1, .pid = 0x0002, .vid = 0x0001, .crpl = MAX_CRPL_SIZE, .num_ele = 1, .ele = { { .path = cli_ele_path_00, .index = PRIMARY_ELE_IDX, .mods = {CFG_SRV_MODEL, CFG_CLI_MODEL}, .vmods = {0xffffffff, 0xffffffff} } } }; ------------------------------------------------ for my untrained eye cli_app_path, cli_agent_path and cli_ele_path_00 look perfectly const. But what do I know?
This code builds fine with gcc-8 or newer. Is there an easy fix for this code to compile with gcc-7, or is the way to go to use "BuildRequires: gcc8" and "export CC=gcc-8" on anything older than Factory?
The issue is that a 'const T' declaration is _not_ a valid constant initializer: const int i = 0; static int j = i; is not valid C. Now, compilers are free to accept extra initializers and there's no diagnostic required so it happens that newer compilers accept more forms of constant expressions for convenience. It doesn't make it valid C though. C18 in 6.6(7) and then (8) still makes this invalid, but as said (10) says "An implementation may accept other forms of constant expressions". It's unfortunate there's no strict mode that diagnoses this consitently. A "fix" would be to use C++ which has constinit / constexpr to force compile-time evaluation (otherwise you risk runtime initialization). Richard. -- Richard Biener <rguenther@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)
Hi Richard, On 18.06.21 08:19, Richard Biener wrote:
The issue is that a 'const T' declaration is _not_ a valid constant initializer:
const int i = 0; static int j = i;
is not valid C. Now, compilers are free to accept extra initializers and there's no diagnostic required so it happens that newer compilers accept more forms of constant expressions for convenience.
Thanks for the explanation. It's beyond my limited understanding of C (and beyond my capabilities) to suggest a fix to upstream. Even patching it to compile on Leap's gcc-7 is apparently not trivial...
It doesn't make it valid C though. C18 in 6.6(7) and then (8) still makes this invalid, but as said (10) says "An implementation may accept other forms of constant expressions".
...and the newer implementations apparently do. So for me, considering the limited usage that a newer bluez package on anything older than Factory will see in general (I just build it in case I see something strange happening on a Leap system, to be able to quickly test if it is fixed in the latest version), the "cheapest" method is to just use the (easily available) gcc-8 to build it on Leap.
It's unfortunate there's no strict mode that diagnoses this consitently.
A "fix" would be to use C++ which has constinit / constexpr to force compile-time evaluation (otherwise you risk runtime initialization).
I'd guess it would be pretty interesting to introduce C++ to upstream for one single testing tool in bluez ;-) The code in question is contributed by intel, maybe I'll try compiling it with intel's compiler, maybe it also does not like that syntax and that will let the authors fix their stuff ;-) Thanks again, seife -- Stefan Seyfried "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." -- Richard Feynman
participants (3)
-
Aaron Puchert
-
Richard Biener
-
Stefan Seyfried