不支持非平凡的指定初始化程序

我的结构如下:

struct app_data
{
int port;
int ib_port;
unsigned size;
int tx_depth;
int sockfd;
char *servername;
struct ib_connection local_connection;
struct ib_connection *remote_connection;
struct ibv_device *ib_dev;


};

当我尝试这样初始化它时:

struct app_data data =
{
.port = 18515,
.ib_port = 1,
.size = 65536,
.tx_depth = 100,
.sockfd = -1,
.servername = NULL,
.remote_connection = NULL,
.ib_dev = NULL
};

我得到了这个错误:

sorry, unimplemented: non-trivial designated initializers not supported

我认为它希望初始化的顺序与声明的一样,而 local_connection缺失了。但是我不需要初始化它,并且将它设置为 NULL 也不起作用。

如果我把 g + + 改成这样,仍然会得到相同的错误:

struct app_data data =
{
port : 18515,
ib_port : 1,
size : 65536,
tx_depth : 100,
sockfd : -1,
servername : NULL,
remote_connection : NULL,
ib_dev : NULL
};
83421 次浏览

这对 g + + 不起作用。您实际上是在 C + + 中使用 C 构造。有几种方法可以绕过去。

1)删除“ .”,并在初始化时将“ =”更改为“ :”。

#include <iostream>


using namespace std;
struct ib_connection
{
int x;
};


struct ibv_device
{
int y;
};


struct app_data
{
int port;
int ib_port;
unsigned size;
int tx_depth;
int sockfd;
char *servername;
struct ib_connection local_connection;
struct ib_connection *remote_connection;
struct ibv_device *ib_dev;


};


int main()
{


struct app_data data =
{
port : 18515,
ib_port : 1,
size : 65536,
tx_depth : 100,
sockfd : -1,
servername : NULL,


local_connection : {5},
remote_connection : NULL,
ib_dev : NULL
};


cout << "Hello World" << endl;


return 0;
}

2)使用 g + +-X c (不推荐)或将此代码放在外部 C 中[免责声明,我还没有测试过这个]

还要注意,正如最初的问题所述,成员表达式的顺序很重要。我注意到,如果我只想在前面的示例中初始化“ size”,那么我需要为。港口及。之前的 ib _ port。否则我得到的错误“对不起,未实现: 非平凡的指定初始化程序不支持”没有那么直观..。

我已经注意到我的 GCC 编译器有一些技巧可以接受。Fieldname = value 赋值,但只有当字段的顺序与在结构中声明的顺序相同时才进行编译。

我可以通过两种方式初始化这个结构。带名称的字段提高了可读性,并降低了以后更改 struct 字段顺序时分配错误数据的风险。

//Declare struct
typedef struct
{
uint32_t const * p_start_addr;
uint32_t const * p_end_addr;
fs_cb_t  const   callback;
uint8_t  const   num_pages;
uint8_t  const   priority;
} fs_config_t;


//Assign unnamed
fs_config_t fs_config
{
(uint32_t*)0x00030000,  // uint32_t const * p_start_addr;
(uint32_t*)0x00038000,  // uint32_t const * p_end_addr;
fs_evt_handler,         // fs_cb_t  const   callback;
8,                      // uint8_t  const   num_pages;
0xFE                    // uint8_t  const   priority;
};


//Assign to named fields
static fs_config_t fs_config1
{
.p_start_addr = (uint32_t*)0x00030000,
.p_end_addr = (uint32_t*)0x00038000,
.callback = fs_evt_handler,
.num_pages = 8,
.priority = 0xFE
};

经验法则是:

  1. 赋值给. name = value 字段
  2. 按照声明的顺序分配
  3. 在作业中包含所有字段

初始化的顺序必须与声明的顺序一致。

typedef struct FOO
{
int a;
int b;
int c;
}FOO;


FOO foo   = {.a = 1, .b = 2}; // OK
FOO foo1  = {.a = 1};         // OK
FOO foo2  = {.b = 2, .a = 1}; // Error sorry, unimplemented: non-trivial designated initializers not supported
FOO foo3  = {.a = 1, .c = 2}; // Error sorry, unimplemented: non-trivial designated initializers not supported

我理解这意味着编译器不支持面向名称的、无序的成员初始化。

需要用老式的方法初始化结构。为了清晰起见,我保留了变量名,但是我必须按顺序初始化它们,而不能跳过一个变量。

我可以停止对任何变量的初始化,但不能初始化由此产生的变量。

不幸的是,C + + 不支持指定的初始化程序。GCC 仍然允许您使用它们(作为一个扩展) ,但是您必须按照 struct中列出的顺序初始化成员。

另一种解决方法是使用立即调用的 lambda:

constexpr fuse_operations fuse_ops = []{
fuse_operations ops{};
ops.destroy = wiifs_destroy;
ops.getattr = wiifs_getattr;
ops.access = wiifs_access;
// ...
return ops;
}();

我个人更喜欢这个解决方案,因为它是完全标准的 C + + ,它可以让你按照你想要的顺序初始化字段,跳过那些你不需要的,默认初始化其余的。编译器仍然是 能够优化这一点。请注意,这只适用于 C + + 17或更高版本。

由于在 Arduino IDE 中没有其他任何一种方法对我有效,所以我决定单独设置每个字段:

struct app_data data;


data.port = 18515;
data.ib_port = 1;
data.size = 65536;
data.tx_depth = 100;
data.sockfd = -1;
data.servername = NULL;
data.remote_connection = NULL;
data.ib_dev = NULL;

我被这个变体击中了,想想这个破解的代码:

enum {
S_START,
S_ANOTHER,
S_LAST
} STATES;


const char* STATE_NAMES[] = {
[S_START] = "S_START",
[S_LAST] = "S_LAST",
};


int main() {
}

下面是错误消息:

a.cpp:10:1: sorry, unimplemented: non-trivial designated initializers not supported
10 | };

问题是我忘记在 STATE _ NAMES 中定义 S _ ANOTER 条目。