話(huà)說(shuō)在一次整理code的時(shí)候,無(wú)意間將一個(gè)原本定義在.c文件中的全局變量移動(dòng)到.h 文件中(此全局變量被多個(gè).c文件使用),然后突然不能生成.ko(linux中可動(dòng)態(tài)裝載的驅動(dòng)模塊).怎么回事?難道是移動(dòng)code的時(shí)候弄錯了?仔細一看提示信息,原來(lái)是 multiple definition.沒(méi)整理之前的code是將此全局變量定義在file***.c 中, 然后在其他的.c中使用的是extern 導入,當時(shí)可以很順利的編成.ko.后來(lái)由于感覺(jué)code不美觀(guān),在整理code的時(shí)候把它提到了file***.h中,讓使用到這個(gè)全局變量的.c都 include file***.h(貌似這樣做不是很好?暫時(shí)不管了).怎么就這么簡(jiǎn)單移動(dòng)了一下code,就會(huì )出現問(wèn)題?(有段時(shí)間沒(méi)寫(xiě) C code了,^_^...).
于是乎,開(kāi)始寫(xiě)一個(gè)簡(jiǎn)單的測試code來(lái)找原因. 下面的幾段估計全世界的會(huì )玩電腦的人都能看懂的code. 先貼上:
//file1.h
#ifndef __FILE1_H__
#define __FILE1_H__
int i;
#endif
//file2.h
#ifndef __FILE2_H__
#define __FILE2_H__
#include "file1.h"
extern void file2_change_i_value(void);
#endif
//file1.c
#include "file1.h"
#include "file2.h"
void main(void)
{
printf("before i = %d\n", i);
file2_change_i_value();
printf("after i = %d\n", i);
}
//file2.c
#include "file2.h"
void file2_change_i_value(void)
{
i = 10;
}
我使用的是linux平臺,所以使用 gcc file1.c file2.c -o file 編譯生成可執行文件file. 嗯??這次居然很順利的生成了file.趕緊執行 ./file, console 打印出如下信息:
before i = 0
after i = 10
回頭看看gcc 編譯過(guò)程中有沒(méi)有類(lèi)似 multiple definition 的error 或 warning 信息,很遺憾,居然也沒(méi)有.難道是現在寫(xiě)的這個(gè)小code沒(méi)有模擬出上面生成.ko文件的原始code. 一想,還確實(shí)有點(diǎn)不一樣的地方,于是乎,把上面的code修改為如下,只需要修改file1.h文件哦.
//file1.h
#ifndef __FILE1_H__
#define __FILE1_H__
int i = 0;
#endif
然后執行 gcc file1.c file2.c -o file , 哈哈,這次就出現 multiple definition of `i' 的提示了.
現在我們來(lái)比較一下2次 file1.h 的區別, 很顯然, 第一次沒(méi)有對 i 賦初值, 而第二次 賦初值為 0. 嗯? 好像int全局變量初始值都是0吧,想想,學(xué)習C語(yǔ)言到現在都第8個(gè)年頭,書(shū)本的知識早也忘記得差不多了.言歸正傳,那既然全局變量 i 2次的的值都是一樣的,為什么會(huì )出現這樣的提示呢?哦,對了,好像有一次, 也是在一個(gè).c文件中定義了一個(gè)全局變量并賦初值,然后直接把定義語(yǔ)句copy到了其他使用它的其他.c文件中,在前面加了一個(gè) extern, 編譯也是 failed. 這2 中現象是不是很相似??
看看C語(yǔ)言課本,自己的理解是,貌似在定義的時(shí)候可以賦初值,聲明的時(shí)候不用賦值,只需要extern一下就OK.至于在.h中定義全局變量,大致也是說(shuō),這樣做的話(huà),多個(gè).c文件在 include .h以后,會(huì )當作又重新定義變量,然后全局變量的命名污染了,就提示 multiple definition 了. 我個(gè)人覺(jué)得是這樣,如有不夠完整或有異義的地方大家可以留言指點(diǎn).....
聯(lián)系客服