为什么指针衰减可以,但外部链接数组作为指针却不行? [重复]

问题描述 投票:0回答:2

既然 C 坚持将数组类型衰减为指针,那么在将数组传递给函数时,为什么将数组作为指针从外部链接到 UB?

举个例子:

我的文件.c

// Declare and initialize a globally available array of integers
int data[5] = { 10, 15, 20, 21, 22 };

我的文件.h

// 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;

Main.c

// 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;
}
arrays c pointers declaration implicit-conversion
2个回答
1
投票

声明必须符合相应的定义。

假设您在一个源文件中有以下定义:

int x[] = { 1, 2, 3 };

在另一个声明中:

extern int *x;

在声明可见的模块中,它期望

x
的字节包含指针值,但它包含数组中包含的值。


0
投票

数组和指针是两种不同的类型。数组可以在表达式中隐式转换为指向它们第一个元素的指针,但这种转换不会发生在同一实体的两个声明之间。因此,如果同一范围内的同一实体将被声明为具有不同的类型,编译器将发出一个实体被重新声明的错误。

例如想象一下,如果这是可能的,那么运算符

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 ) );
    //..

会输出什么?

指针占用的内存包含一个地址。另一方面,数组占用的内存包含数组元素。

© www.soinside.com 2019 - 2024. All rights reserved.