繁体   English   中英

当按引用传递时,C++ 如何检查数组的大小

[英]How does C++ checks an array's size when passed by reference

当通过引用函数传递数组时,例如:

void Foo(double (&MyList)[3]);

当您尝试向此函数传递大小为 3 的数组时,代码将无法编译。 根据我在 C++ 中的理解,一旦实例化,就无法知道数组的大小。

编译器如何能够跟踪数组的大小? 为什么那么,如果它能够检查数组的大小,这样的代码仍然可以编译?

int MyTab[3]
MyTab[3] = 5;

C++ 只能跟踪具有自动或静态存储持续时间(即局部或全局变量)的数组的大小,因为这是固定大小数组可以存在的唯一地方(因此数组类型的变量只能引用这些)。 令人困惑的部分是允许数组衰减为指针,这可能会很快发生(例如,如果您将数组作为函数参数传递而没有参数是数组的引用)。

void foo(int i[]);  // i will be a pointer, not an array

template <std::size_t N>
void foo(int (&i)[N]);   // i is a reference to an array with size N

具有动态存储期的数组(即使用new创建的数组)不能被数组类型引用,因为这样的数组必须具有编译时已知的大小,而new可以创建动态数组(大小可能仅在运行时才知道)。 因此, new为您提供了一个指向数组第一个元素的指针,此时编译器无法再为您提供帮助。

int i[] = new int[10];  // i is not an array, it's a pointer
int i[10];              // i is an array, the array is located on the stack

关于你的

int MyTab[3];
MyTab[3] = 5;

例如,让我们引用cppreference

内置下标表达式 E1[E2] 与表达式 *(E1 + E2) 完全相同

翻译成你的情况:

MyTab[3]*(MyTab + 3)相同,我们可爱的指针再次衰减。 operator+对指针和整数进行操作,因此MyTab再次衰减为指针,丢失其所有大小信息。

除此之外,您仍然可以通过越界访问获得结束迭代器(您只是不允许读取或写入值):

int* begin = MyTab;   // pointer decay again, equal to &MyTab[0]
int* end = &MyTab[3]; // get a pointer to one past the end (aka end iterator)

编译器确实可以警告您更大的越界访问,但不确定为什么不这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM