既然 C 坚持将数组类型衰减为指针,那么在将数组传递给函数时,为什么将数组作为指针从外部链接到 UB?
举个例子:
// Declare and initialize a globally available array of integers
int data[5] = { 10, 15, 20, 21, 22 };
// Extern the array as a pointer, instead of an int-array
// It *looks* like the array decays to pointer, but is technically UB.
extern int *const data;
// Bring in the declaration of data as a const-pointer.
#include "MyFile.h"
int main(void)
{
// Try to set a member of the array. UB!
data[4] = 0;
// Try to use data. Technically UB!
printf("Value is %d\n", data[4]);
return 0;
}
声明必须符合相应的定义。
假设您在一个源文件中有以下定义:
int x[] = { 1, 2, 3 };
在另一个声明中:
extern int *x;
在声明可见的模块中,它期望
x
的字节包含指针值,但它包含数组中包含的值。
数组和指针是两种不同的类型。数组可以在表达式中隐式转换为指向它们第一个元素的指针,但这种转换不会发生在同一实体的两个声明之间。因此,如果同一范围内的同一实体将被声明为具有不同的类型,编译器将发出一个实体被重新声明的错误。
例如想象一下,如果这是可能的,那么运算符
sizeof
应该为这样的实体返回什么值?指针的大小还是数组的大小?
考虑你自己的代码。
// Bring in the declaration of data as a const-pointer.
#include "MyFile.h"
int main(void)
{
// Try to set a member of the array. UB!
printf( "sizeof( data ) = %zu\n", sizeof( data ) );
//..
会输出什么?
指针占用的内存包含一个地址。另一方面,数组占用的内存包含数组元素。