我在遗留项目中看到了下面的代码.
/* token.c */ struct token id_tokens[MAX_TOKENS]; /* analyse.c (v1) */ extern struct token *id_tokens; /* Raised my eyebrow,id_token declares a pointer */
我坚持改变analyse.c来包含如下声明:
/* analyse.c (v2) */ extern struct token id_tokens[]; /* I am happy with this. id_tokens declares array of unspecified size. */
我想要v2,因为T的指针与T的数组不一样.我的朋友的反对者认为两者的行为是一样的,所以我是否使用v1和v2并不重要.
问题1:不完整类型的数组是否耗尽指针?
问题2:我的朋友是否对这两个版本的行为保证是等同的?
解决方法
/* token.c */ struct token id_tokens[MAX_TOKENS]; /* id_tokens +-----+-----+-----+-----+...+-----+ | | | | | | | +-----+-----+-----+-----+...+-----+ [0] [1] [2] [3] ... [MAX_TOKEN-1] To access id_tokens[i],add offset of ith element i.e. i * sizeof(struct token) to the **address** of array token */
因此,在您的analyse.c中,将使用此声明生成以下说明.
extern struct token id_tokens[];
id_tokens[i]
a. Address of id_tokens that might be linked from other compilation unit
is taken
b. offset of i is added
c. Value is referenced
/* analyse.c (v1) */ extern struct token *id_tokens; /* id_tokens +------+ +-----+... | addr |---------->| | +------+ +-----+... To access id_tokens[i],fetch **contetnts** of pointer token,add offset of ith element i.e. i * sizeof(struct token) is added to this. */
因此,将使用此声明生成以下说明:
extern struct token *id_tokens;
id_tokens[i]
a. Contents from address of id_tokens that is linked from other
compilation unit is taken.
(Will result in compilation error if present in same compilation unit because of type mismatch)
b. offset of i is added
c.
Value is referenced
我们假设sizeof id_token [0]是2字节,sizeof指向id_token [0]的指针是4字节.
你以后的声明可能(误)插入id_tokens [0]& id_tokens [1]作为地址,并添加一些偏移量(可能是现有或不存在的地址,对齐或不对齐的地址谁知道).
如果这是您的美好日子,程序可能会立即崩溃或破坏,并有机会修复错误.如果这是糟糕的一天,程序可能会混乱一些其他内存,或者向一些模块传达错误的状态,这可能导致难以追踪错误并导致噩梦.
现在我想你明白为什么你在Mr. 32’s answer年(零)作为输出.