Gya*_*ain 8 c declaration extern language-lawyer
我在遗留项目中看到了以下代码段.
/* token.c */
struct token id_tokens[MAX_TOKENS];
/* analyse.c (v1) */
extern struct token *id_tokens; /* Raised my eyebrow, id_token declares a pointer */
Run Code Online (Sandbox Code Playgroud)
我坚持要改变analyse.c以包含如下声明:
/* analyse.c (v2) */
extern struct token id_tokens[]; /* I am happy with this. id_tokens declares array of unspecified size. */
Run Code Online (Sandbox Code Playgroud)
我想v2因为pointer to T不一样array of T.我朋友的反驳说,两者的行为都是一样的,所以我使用v1和v2并不重要.
问题1:不完整类型的数组是否耗尽指针?
问题2:我的朋友是对的,两个版本在行为上都保证是等价的吗?
第一个版本是错误的.数组不是指针,声明extern struct token *id_tokens;与定义类型不匹配struct token id_tokens[MAX_TOKENS];.
参考:C FAQ:我在一个源文件中定义了char [6],在另一个源文件中我声明了extern char*a.它为什么不起作用?.另外,看到这个.
/* 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
*/
Run Code Online (Sandbox Code Playgroud)
因此analyse.c,在您的 中,将使用此声明生成以下指令。
extern struct token id_tokens[];
id_tokens[i]
a. 获取可能从其他编译单元链接的 id_tokens 的地址
b.添加 i 的偏移量
c. 值被引用
/* 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.
*/
Run Code Online (Sandbox Code Playgroud)
因此analyse.c,在您的 中,将使用此声明生成以下指令:
extern struct token *id_tokens;
id_tokens[i]
a. 获取从其他编译单元链接的 id_tokens 地址的内容。
(如果由于类型不匹配而出现在同一编译单元中,将导致编译错误)
b.添加 i 的偏移量
c. 值被引用
假设 sizeofid_token[0]是2字节,sizeof 指针是id_token[0]字节4。
您稍后的声明可能(错误)将id_tokens[0]&解释id_tokens[1]为地址,并向其添加一些偏移量(可能是现有或不存在的地址,对齐或不对齐的地址谁知道)。
如果今天运气好,程序可能会立即崩溃或出现段错误,并且您有机会修复错误。如果今天心情不好,程序可能会弄乱其他内存或向某些模块传达错误的状态,这可能会导致难以跟踪错误并引发噩梦。
现在我想你明白为什么你在32 先生的答案(nil)中得到了输出。
| 归档时间: |
|
| 查看次数: |
341 次 |
| 最近记录: |