Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用指向指针数组成员的指针进行静态结构初始化_C_Visual Studio_Visual C++_C99 - Fatal编程技术网

C 使用指向指针数组成员的指针进行静态结构初始化

C 使用指向指针数组成员的指针进行静态结构初始化,c,visual-studio,visual-c++,c99,C,Visual Studio,Visual C++,C99,我试图初始化一个需要指向指针数组的结构成员。其思想是静态声明结构数组以避免初始化开销,因为所有数据在编译时都是固定的和已知的 不幸的是,我无法在Visual Studio 2015下编译代码。下面列出的代码产生以下错误:C2099:初始值设定项不是常量。这看起来很奇怪,因为list仅使用固定大小的字符串文本列表进行初始化 #define DATA_LIST { \ L"some", \ L"example", \ L"data", \

我试图初始化一个需要指向指针数组的结构成员。其思想是静态声明结构数组以避免初始化开销,因为所有数据在编译时都是固定的和已知的

不幸的是,我无法在Visual Studio 2015下编译代码。下面列出的代码产生以下错误:
C2099:初始值设定项不是常量
。这看起来很奇怪,因为
list
仅使用固定大小的字符串文本列表进行初始化

#define DATA_LIST { \
    L"some",        \
    L"example",     \
    L"data",        \
    L"in a list",   \
    NULL            \
}

#define INFO_LIST { \
    L"another",     \
    L"list",        \
    L"with",        \
    L"some",        \
    L"info",        \
    NULL            \
}

typedef struct data {
    unsigned int flag;
    const wchar_t **list;
} dataset, *pdataset;

static dataset somedata[] = {
    {   .flag = 2,
        .list = (const wchar_t *[])DATA_LIST // C2099
    },
    {   .flag = 4,
        .list = (const wchar_t *[])INFO_LIST // C2099
    }
};
我还尝试使用指向灵活数组的指针(
constwchar\u t*list[];
)。这不是理想的解决方案,因为
somedata
将不再能够声明为结构数组。接下来,它还将生成一个警告
(C4200:使用的非标准扩展:struct/union中的零大小数组)

另一个想法是将
list
定义为指向固定大小指针数组的指针。但这需要使用足够大的
列表
成员来定义
数据集
结构。当有很多小列表和一个大列表时也不理想

typedef struct data {
    unsigned int flag;
    const wchar_t *list[sizeof (wchar_t *[])INFO_LIST / sizeof *(wchar_t *[])INFO_LIST];
} dataset, *pdataset;

static dataset somedata[] = {
    {   .flag = 2,
        .list = DATA_LIST
    },
    {   .flag = 4,
        .list = INFO_LIST
    }
};
也许我正在监督一些事情,或者是否有一些语言扩展功能可以提供一个优雅的解决方案?欢迎提出任何建议

注意:即使添加了
visual-c++
标记,代码仍编译为c代码


另一件有趣的事情是,当
somedata
声明为非静态时(因此没有
static
关键字),编译器将产生一些警告,但能够编译代码。通过将
somedata
声明为非静态,将删除强制用于初始化
somedata
的数据在编译时已知的约束

如编译警告所示,编译器似乎在初始化
list
成员之前,将字符串文本列表的地址临时存储在自动变量中。不过,这仍然是猜测。也许有经验的人可以解释一下这里到底发生了什么

typedef struct data {
    unsigned int flag;
    const wchar_t **list;
} dataset, *pdataset;

// C4221: nonstandard extension used: 'list': cannot be initialized using
//        address of automatic variable '$S1'
// C4204: nonstandard extension used: non-constant aggregate initializer
dataset somedata = {
    .flag = 2,
    .list = (const wchar_t *[])DATA_LIST // note: see declaration of '$S1'
};
最后但并非最不重要的一点是,当使用用字符串文本列表的地址初始化的临时变量初始化
列表
成员时,代码最终编译良好,没有任何警告或错误

static const wchar_t *temp[] = DATA_LIST;

static dataset somedata = {
    .flag = 2,
    .list = temp
};
但是当将
temp
声明为指向指针的指针并键入字符串文本列表时,无法再编译代码,因为初始化
list
的表达式被标记为活动错误:
表达式必须具有常量值

static const wchar_t **temp = (const wchar_t *[])DATA_LIST;

static dataset somedata = {
    .flag = 2,
    .list = temp // marked as active error
};
如果我决定再次使
somedata
非静态,则表达式不再标记为活动错误。但在尝试编译代码时,再次出现以下错误:
C2099:初始值设定项不是常量


我想知道Visual Studio 2017是否有相同的行为方式,是否有可用的替代方法以类似的方式组织和处理数据。

MSVC对C标准的遵从性较差。作为一种解决方法,您可以使用命名对象而不是复合文字:

static const wchar_t *x_data_list[] = DATA_LIST;
static const wchar_t *x_info_list[] = INFO_LIST;

static dataset somedata[] = {
    {   .flag = 2,
        .list = x_data_list
    },
    {   .flag = 4,
        .list = x_info_list
    }
};


我不确定您是否有意将列表设置为非常量,但如果您不打算在运行时写入
x_data_list
,则可以将其设置为
const
,并将
.list
成员的类型设置为
const wchar\t*const*

static const wchar_t *x_data_list[] = DATA_LIST;
static const wchar_t *x_info_list[] = INFO_LIST;

static dataset somedata[] = {
    {   .flag = 2,
        .list = x_data_list
    },
    {   .flag = 4,
        .list = x_info_list
    }
};


我不确定您是否有意将列表设置为非常量,但如果您不打算在运行时写入
x_data_list
,那么您可以将其设置为
const
,并将
.list
成员的类型设置为
const wchar*const*

Visual studio对C99的支持实际上是不存在的。这就是你没能成功的原因。如果您希望MSVC构建代码,请坚持使用C90。16年的时间不足以让MS实现新功能,请再给他们几年。Visual studio对C99的支持几乎不存在。这就是你没能成功的原因。如果您希望MSVC构建您的代码,请坚持使用C90。16年的时间不足以让MS实现新功能,请再给他们几年时间
const
应用到左侧,这就是为什么我总是在右侧
wchar\u t const*const*
,我发现
const-wchar\u t*const*
奇怪,因为人们认为
const
适用于右边。
const
适用于左边这就是为什么我总是在右边写
wchar\u t*const*
,我发现
const-wchar\u*const*
奇怪,因为人们认为
const
适用于右边。