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)