linux纯内核直接用吗,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等編譯命令,將源程序文件中的部分包含進來,部分排除,排除在外的一般轉換為空行
總結
以上是生活随笔為你收集整理的linux纯内核直接用吗,Linux:为啥内核有的变量没有初始化就敢直接使用?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多选取值_机制砂如何控制MB值和石粉含量
- 下一篇: android一个工程的xml怎么引用另