侵权投诉
搜索
更多>> 热门搜索:
订阅
纠错
加入自媒体

Linux:为啥内核有的变量没有初始化就敢直接使用?

2021-03-30 14:25
一口Linux
关注

一、问题

为啥内核有的变量没有初始化就敢直接使用?

二、分析

看上图,其中的5747行的变量nid的确没有定义,就直接使用了,这么做没有问题吗?

其实大家仔细看一下,5765行是一个宏,

到内核源码去找该宏的定义:linux-3.14includelinuxNodemask.h

#define for_each_online_node(node) for_each_node_state(node, N_ONLINE)

其中的for_each_node_state又是一个宏,继续跟踪该宏,有两处定义

408 #if MAX_NUMNODES > 1
……
429 #define for_each_node_state(__node, __state)
430  for_each_node_mask((__node), node_states[__state])
……
450 #else
……
470 #define for_each_node_state(node, __state)
471  for ( (node) = 0; (node) == 0; (node) = 1)
……
481 #endif

究竟是哪一个定义,由条件#if MAX_NUMNODES > 1 来决定,

#ifdef CONFIG_NODES_SHIFT
#define NODES_SHIFT     CONFIG_NODES_SHIFT
#else
#define NODES_SHIFT     0
#endif
#define MAX_NUMNODES    (1 << NODES_SHIFT)

因为CONFIG_NODES_SHIFT没有定义【可以检索一下内核,找不到该宏的定义】,所以NODES_SHIFT     为0

所以 MAX_NUMNODES   为1;

所以 for_each_node_state 定义如下:

470 #define for_each_node_state(node, __state)
471  for ( (node) = 0; (node) == 0; (node) = 1)

而此处的node      对应 粉丝截图的nid,__state  对应 N_ONLINE

所以5765行代码,可以展开为

for ( (nid) = 0; (nid) == 0; (nid) = 1)

可见,nid被定义了。

三、宏定义的注意点

宏定义是一个给定名称的代码片段,当我们使用这个名称的时候,预处理器会自动将其替换为宏定义的内容。宏定义有两种,一种是object-like宏定义,在使用的时候相当于一个数据对象;另一种是function-like,在使用的时候就像调用函数那样。

1. 只占用编译时间

宏展开会使源程序变长,但是宏展开发生在编译过程中,不占运行时间,只占编译时间。

宏展开因为在预处理阶段发生,不会分配内存。

2. 宏替换发生时机

编译c源程序的过程:

预处理编译汇编连接

宏替换发生在编译预处理阶段。

3. 预处理包括哪些工作

预处理产生编译器的输出,实现功能如下

1)文件包含

把#include中包含的内容拓展为文件的正文,即找到.h文件,同时展开到#include所在处

2)条件编译

根据#if和#ifdef等编译命令,将源程序文件中的部分包含进来,部分排除,排除在外的一般转换为空行

1  2  3  下一页>  
声明: 本文由入驻维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。

发表评论

0条评论,0人参与

请输入评论内容...

请输入评论/评论长度6~500个字

您提交的评论过于频繁,请输入验证码继续

暂无评论

暂无评论

    文章纠错
    x
    *文字标题:
    *纠错内容:
    联系邮箱:
    *验 证 码:

    粤公网安备 44030502002758号