我正在努力理解在C++中编写int arr[];
是否有效。举个例子:
int a[]; //is this valid?
extern int b[];//is this valid?
int (*ptrB)[]; //is this valid?
struct Name
{
int k[]; //is this valid?
};
void func()
{
ptrB++; //is this valid?
}
int a[10];
int b[10];
void bar()
{
ptrB = &b;//is this valid?
ptrB++; //is this valid?
}
int main()
{
int c[];//is this valid?
extern int d[]; //is this valid?
}
int c[10];
int d[10];
我已经阅读了一些关于SO的评论,指出int p[];
不是有效的C++。所以我想知道在什么情况下这是有效的/无效的。为此,我写了上面的片段,并希望通过这个例子来理解。
让我们看看每种情况。
情况1
这是的声明
int a[]; //this is a definition so size must be known
这是无效的。
情况2
我们有一个声明:
extern int b[];//this is a declaration that is not a definition
这是有效。这里b
的类型是不完全。此外,b
具有外部链接。
情况3
我们有:
int (*ptrB)[];
这是有效。我们说ptrB
是指向不完整类型的指针。
情况4
我们有:
struct Name
{
int k[]; //NOT VALID
};
这是无效,因为来自cppreference:
以下任何上下文都要求类型T是完整的:
- 类型为T的非静态类数据成员的声明
情况5
我们有:
void func()
{
ptrB++; //NOT VALID
}
这是无效,因为从后缀增量的文档来看:
内置后缀递增或递减运算符的操作数expr必须是非布尔(自C++17以来(算术类型的可修改(非常量(左值,或指向完全定义的对象类型的指针。
案例6
我们有:
void bar()
{
ptrB = &b;//NOT VALID
}
这是无效,因为来自cppreference:
数组对象的声明类型可能是一个未知边界的数组,因此在转换单元中的某一点上是不完整的,稍后是完整的;在这两个点上的数组类型("T的未知界数组"one_answers"NT的数组"(是不同的类型。
案例7
我们有:
void bar()
{
ptrB++; //NOT VALID
这是无效,因为来自cppreferene:
指向未知绑定数组的指针的类型,或指向typedef声明定义为未知绑定数组类型的指针的类型不能完成。
因此,我们将得到与情况5相同的错误。
情况8
我们有:
int main()
{
int c[];
}
这是无效,因为这是一个定义,所以大小必须是已知的。
情况9
我们有:
int main()
{
extern int d[]; non-defining declaration
}
这是有效。d
具有外部链接。