gcc C99指示符成员在聚合初始值设定项之外

jobtbby3  于 2023-01-05  发布在  其他
关注(0)|答案(3)|浏览(244)
struct Foo {
    char a[10];
    int b;
};

static Foo foo = {.a="bla"};

编译上述代码时会出现以下gcc错误:

$ gcc -std=gnu++2a test.cpp 

C99 designator ‘a’ outside aggregate initializer

我以为在C++20中初始化器列表中的C字符串指示符是可以的?我遗漏了什么?我使用的是gcc版本10。

abithluo

abithluo1#

这是GCC的一个已知错误:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55227
不幸的是,你要么不使用指定的初始化器,要么为数组使用不同的初始化器:

static Foo foo = {"bla"};
static Foo foo = {.a={'b', 'l', 'a', 0}};
wvt8vs2t

wvt8vs2t2#

我得到了相同的错误,并处理了mv my.cpp my.c
您也可以在此链接中找到答案:https://pcbartists.com/firmware/esp32-firmware/designator-outside-aggregate-initializer-solved/

#ifdef __cplusplus
extern "C"
{
#endif

    // C code goes here
    
#ifdef __cplusplus
}
#endif
s71maibg

s71maibg3#

我使用strncpy(来自<cstring>),例如:

strncpy(foo.str, "hello", sizeof(foo_t::str));

它似乎被优化掉了,因此在较新的GCC(11.3^)中生成了与正常方法相同的汇编,并且与使用char数组的Artyer解决方案(被接受的解决方案)相同。
Godbolt链接:https://godbolt.org/z/9G7b6PT9b
但是,如果启用了-Wextra警告,则解决方案可能会导致warning: missing initializer for member 'foo_t::str' [-Wmissing-field-initializers],但您可以使用-Wno-missing-field-initializers排除它。
顺便说一下,使用stuct时,你必须记住空间是有限的,在很多情况下你可能想在字符串末尾留下尾随零。使用strncpy时,你可以通过添加以下内容来强制:

foo.str[sizeof(foo_t::str) - 1] = 0;

相关问题