[英]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.