c - C结构体数组的初始化
问题描述
Unix 6 源代码。很古老。
配置文件
struct bdevsw {
int (*d_open)();
int (*d_close)();
int (*d_strategy)();
int *d_tab;
} bdevsw[];
conf.c
int (*bdevsw[])(){
&nulldev, &nulldev, &rkstrategy, &rktab,
&nodev, &nodev, &nodev, 0,
0
}
我的问题为什么不初始化只是读取,
bdevsw[] = {......}
解决方案
为这个答案收集的所有信息都来自我值得信赖的狮子会评论书副本。它是非常早期的 UNIX 代码的一个很好的资源。
如果您将声明的怪物注入cdecl,您会发现它的目的是:
声明
bdevsw
为指向函数返回的指针数组int
。
因此,它根本不是代码(a),而是函数的数组定义,每个设备一个,与您的建议几乎相同。
它不在头文件中的原因可能是以下原因。
首先,该conf.c
文件实际上是由自动生成的mkconf
,因为该文件包含给定 UNIX 系统的设备详细信息(块和字符设备,保存在bdevsw
和中cdevsw
)。
作为一个自动生成的文件,将数据类型的声明(在不同系统之间是一致的)和数组的定义(每个系统都会改变)分开是有意义的。该文件顶部的注释表明它和low.s
是 的结果mkconf
。
其次,有不少 C 文件包含conf.h
. 例如,bio.c
(块 I/O)、sys3.c
(文件系统调用)、fio.c
(文件调用)和alloc.c
(非常早的初始化以读取根超级块)。
所以,如果在头文件中定义了数组(大概是static
为了防止双重定义),每个源文件基本上都有自己的副本,浪费了宝贵的空间。通过在 中定义它conf.c
,每个人都共享一个副本。
(a)你的评论是:
初始化 stmt 中的第二个括号使它看起来像一个函数
是可以理解的,在这种情况下,它确实代表了一个函数调用。但仅限于它是指向函数的指针数组,而不是实际的函数定义。
推荐阅读
- java - 基于 findElements 循环遍历列表是如何工作的?
- kubernetes - 防止 Terraform 模块使用默认 kubeconfig
- c++ - ASIOSDK;从 hostsample.cpp 构建 mex 文件时出错
- sql - 查询具有未来 20 分钟内日期/时间的项目
- html - 在单独的路线上渲染卡片内容 [Angular]
- php - 显示总值时在 php 中遇到格式不正确的数值
- powershell - 在 Where-Object 条件之后获取第一个值
- python - ValueError:x和y在python的线性回归中必须具有相同的第一维
- swift - 使用 Siri 处理意图参数和动态选项的错误
- vim - vim 中的 ripgrep :term