C++ 错误:无法转换';常量无符号字符(*)[7]';至';常量无符号字符(*)[]';在初始化中

C++ 错误:无法转换';常量无符号字符(*)[7]';至';常量无符号字符(*)[]';在初始化中,c++,c,C++,C,我正在尝试构建一种基本的数据库(或者更确切地说是数据存储)结构,以存储不同项目到特定测试用例的映射,这意味着要在Arduino上运行-因此存储空间效率是一个主要问题 因此,我编写了两个typedef和struct,仅头文件就可以很好地编译。但是,当我想要创建结构实例来实际存储数据时,我遇到了几个错误,这些错误似乎与第一个非常相似: error: cannot convert 'const uint8_t (*)[7] {aka const unsigned char (*)[7]}' to 'c

我正在尝试构建一种基本的数据库(或者更确切地说是数据存储)结构,以存储不同项目到特定测试用例的映射,这意味着要在Arduino上运行-因此存储空间效率是一个主要问题

因此,我编写了两个typedef和struct,仅头文件就可以很好地编译。但是,当我想要创建结构实例来实际存储数据时,我遇到了几个错误,这些错误似乎与第一个非常相似:

error: cannot convert 'const uint8_t (*)[7] {aka const unsigned char (*)[7]}' to 'const uint8_t (*)[] {aka const unsigned char (*)[]}' in initialization
要再现此错误,仅以下4行相关:

-在我的头文件中 (请注意,这些注释说明了我对该行的期望,而不是它是什么;)

-在我的代码文件中:

const Testcase ic_1tc_1 = {0x00, 0x10, 0x01, 0x61, 0x00, 0x30, 0x07};

Sequence s1 = {&ic_1tc_1};
错误发生在代码文件的第二行,我希望创建一个数组,其中有一个指向testcase的指针元素

我发现的所有类似问题都是关于“const”关键字的问题,我想我已经整理好了,所以它们对我没有帮助

我理解编译器错误是告诉我的 “我无法将长度为7的数组转换为任意长度的数组” 这对我来说毫无意义


谁能给我解释一下吗;医生:

替换

Sequence s1 = {&ic_1tc_1};


说明:

让我们从简单的事情开始

在定义中省略数组大小时,将推导出该大小:

int x[] = {1,2,3};
这里,
x
的类型是
int[3]

请注意,类型不是
int[]
。表示未知绑定数组的类型是不完整的类型,无法创建此类类型的对象

即使使用
typedef
s,上述功能也能正常工作:

typedef int array[];
array x = {1,2,3};
请注意,
x
的类型不是
array
,因为它是
int[3]
而不是
int[]


即使不能创建不完整类型的对象,也可以创建指向此类类型的指针

例如:

int (*ptr)[];
本声明与下列声明具有同等效力:

typedef int array[];
array *ptr;
该指针只能指向
int[]
,但由于无法创建此类对象,因此不经常使用指向未知边界数组的指针

(尽管我可以想象一些特殊的用例。你可以声明一个数组有一个未知的边界,并在其他地方定义它时指定一个大小。然后你可以使用声明形成一个指向数组的指针,这样的指针的类型将是
T(*)[]

您不能将地址
int[N]
分配给这样的指针,因为形式上
int[]
int[N]
是不同的类型

typedef int array[];
array x = {1,2,3};
array *ptr = &x; // Error, can't convert `int(*)[3]` to `int(*)[]`.
这正是您试图在代码中执行的操作

一种可能的解决方案是为指针使用正确的类型:

typedef int array[];
array x = {1,2,3};
int (*ptr)[3] = &x;
但是,既然您说需要一个指向各种大小数组的指针数组,那就不是一个选项

另一种可能的解决方案是强制转换指针,但这看起来并不方便(而且我不能100%确定使用结果指针是否定义良好)

您可能应该只存储指向数组第一个元素的指针:

typedef int array[];
array x = {1,2,3};
int *ptr = x;
在您的代码中,它看起来是这样的:

const Testcase ic_1tc_1 = {0x00, 0x10, 0x01, 0x61, 0x00, 0x30, 0x07};
const uint8_t *s1[] = {ic_1tc_1};

错误可以更好地表示为“无法将指向长度为7的数组的指针转换为指向任意长度数组的指针”。您不能将指向不同类型的指针相互转换(通常)。你可能会更好地解释你想要实现的目标,而不是询问关于这些细节的问题。@Lundin:如果你说的“不完整类型的数组”,你指的是元素类型不完整的数组,情况并非如此。
Testcase
的元素是
const uint8\u t
,而
Sequence
的元素是指针。@EricPostpischil如果大小不存在,则数组类型是不完整的类型。6.7.6.2.@Lundin:“不完整类型的数组”是指数组的类型不完整,而不是数组的类型不完整?那你的措辞就不清楚了。那么,“类型不完整、类型未知的数组”意味着什么呢?如果
Testcase
是一个不完整类型的数组,因为数组大小未知,“未知类型”是什么?
Testcase
定义中的另一种类型,其元素类型是
const uint8\u t
,因此它是已知的。此外,在C中可以使用未知大小的数组(使用它们与定义它们不同),并且可以使用指向未知大小数组的指针。即使是真的,缺乏知识肯定不是一种不变的状态,所以说“就是这样”是错误的。你应该停止批评人们的知识状况。Re“从语言的角度来看,
int[]
int[N]
是不同的不相关类型”:“语言”是含糊不清的;这个问题被标记为C和C++。在C中,类型不是无关的;它们是相容的。@ericshil我会想出更好的措辞。:)“它们是兼容的。”你能详细说明一下吗?C 6.7.6.2 6说,如果数组类型具有兼容的元素类型,并且没有不同的常量长度,那么它们是兼容的。因此,如果一个或两个数组具有未指定的长度或可变长度,则类型是兼容的。(这意味着C允许你做一些不好的事情,比如把一个指向长度为7的可变长度数组的指针分配给一个指向长度为4的可变长度数组的指针。)@HolyBlackCat谢谢你的回答,我会试试的。根据你的解释,我不明白为什么第1行,测试用例定义,可以工作?Testcase是
uint8\u t[]
但值是
uint8\u t[7]
此外,我可以创建另一个不同长度的Testcase类型的对象,它编译得很好
typedef int array[];
array x = {1,2,3};
int *ptr = x;
const Testcase ic_1tc_1 = {0x00, 0x10, 0x01, 0x61, 0x00, 0x30, 0x07};
const uint8_t *s1[] = {ic_1tc_1};