一、问题

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

二、分析

看上图,其中的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等编译命令,将源程序文件中的部分包含进来,部分排除,排除在外的一般转换为空行

linux纯内核直接用吗,Linux:为啥内核有的变量没有初始化就敢直接使用?相关推荐

  1. Linux: 不用密码直接用ssh 登入到远端电脑(RAS/DSA认证)

    1. DAS认证 多 年前telnet 当道,但在安全意识渐渐浮上台面之后,telnet 在登入时的安全就被大家质疑,后来ssh (Secure Shell) 出现时,改变​​了当初的习惯,大家在管理 ...

  2. usb网卡在linux上能直接用吗,关于usb网卡如何在红旗linux6.0上使用的问题

    下文仅供参考 因为我安装的是自带的无线网卡.我想原理应该差不多: 你先准备好windows下使用的网卡驱动和ndiswrapper 1.53 这是我的blog上的文章 系统:红旗Linux桌面版 6. ...

  3. linux内核开发基础(linux内核源码、树莓派源码编译、SD卡挂载)

    首先下载树莓派linux内核源码: 下载网址:https://github.com/raspberrypi/linux 在树莓派使用指令:uname -r查看当前树莓派的版本号,然后选择对应的linu ...

  4. linux源码gpio模拟i2c,linux内核gpio模拟i2c实例.doc

    linux内核gpio模拟i2c实例.doc linux内核GPIO模拟I2C实例2010-10-11作者:cvip302814来源:cvip302814的blog前言:在许多情况下,我们并没有足够的 ...

  5. 查看linux的系统命令,命令行查看Linux的系统版本和内核版本以及机器字长

    查看Linux版本 1.  lsb_release -a        (适用于所有linux) 复制代码 代码如下: LSB Version: :base-4.0-ia32:base-4.0-noa ...

  6. linux vdso(Virtual Dynamically-linked Shared Object)内核态的调用映射到用户态的地址空间开销更小

    VDSO(Virtual Dynamically-linked Shared Object)是个很有意思的东西, 它将内核态的调用映射到用户态的地址空间中, 使得调用开销更小, 路径更好. 开销更小比 ...

  7. 不属于linux内核锁的是,Linux内核中的锁

    1. 为什么要保证原子性 处理器分两种:cisc(复杂指令集,可以直接在内存上进行操作,如x86,一条汇编指令可以原子的完整读内存.计算.写内存)和rics(精简指令集,所有操作都必须是在CPU内部进 ...

  8. linux编译内核实验,实验六 Linux内核编译实验.doc

    实验六 Linux内核编译 讲师:杨行 [实验目的] 1.掌握Linux内核编译 2.了解Linux内核Makefile 3.了解Linux内核Kbuild系统 [实验原理] 网站可以下载标准内核文件 ...

  9. linux选择运行的核数量,linux – 如何根据可用内核的数量选择最大负载阈值?

    负载在Linux上经常被误解. 在Linux上,它是运行或不间断睡眠状态中所有任务的度量. 请注意,这是任务,而不是进程.线程包含在此值中. 内核每五秒计算一次加载,并且是一个加权平均值.这是微小负载 ...

最新文章

  1. java: BigDecimal 调用add后,求和结果没有变化
  2. 自学编程需要注意什么?
  3. [vim] vim中使用cscope的安装与使用
  4. 怎样在vs中监视char*字符串_字符串指针数据类型
  5. 华为交换机telnet和ftp服务开启/关闭命令
  6. java代码god类_java – 如何编写Controller而不将其作为God对象?
  7. ajax提交数据被截断的问题
  8. 域控服务器取消验证_Linux 开发笔记《使用CentOS 7进行初始服务器设置》
  9. android平台Camera采集数据ffmpeg进行编码探究
  10. ADO SQL手写分页
  11. AIScanner文字识别软件 OCR
  12. 学习matlab体会,matlab学习心得体会
  13. AI今年最大进展就是毫无进展?2019年AutoML、GAN将扛大旗
  14. 在阅读中培养自己的注意力
  15. 软件设计模式——建造者模式
  16. 数据库日常运维操作手册
  17. 关于pywin32引起python应用退出时c0000005错误的分析和解决
  18. 走近Ts,用了爽,用后一直爽(二)
  19. 智慧城市与数字政府、城市大脑、一网统管之间什么关系
  20. android控制电路板的开关灯,一文解读LED触摸调光台灯控制电路板的工作原理

热门文章

  1. c3等待加载样式 vue_Vue.js__简易加载等待动画
  2. python爬取微博内容_请问该如何通过python调用新浪微博的API来爬取数据?
  3. python字符串变量s的值是python网络爬虫_【Python爬虫作业】-字符串
  4. 神经网络的全连接层_深度神经网络全连接层
  5. 【译】Googler如何解决编程问题
  6. 浏览器拦截跨域请求处理方法(已阻止跨源请求:同源策略禁止读取远程资源)
  7. “玲珑杯”线上赛 Round #15 河南专场 F 咸鱼文章
  8. LCD显示屏原理与应用
  9. 关于模拟器Hyper-v中的Wp8网络连接问题
  10. char与varchar区别(MYISAM)