欧美日韩不卡一区二区三区,www.蜜臀.com,高清国产一区二区三区四区五区,欧美日韩三级视频,欧美性综合,精品国产91久久久久久,99a精品视频在线观看

C語言

C 語言聲明與定義不一致導(dǎo)致的問題

時間:2025-05-12 02:50:39 C語言 我要投稿
  • 相關(guān)推薦

C 語言聲明與定義不一致導(dǎo)致的問題

  我們在寫代碼的時候,往往只注意函數(shù)的實現(xiàn),對函數(shù)的聲明重視不足。下面是小編為大家?guī)淼腃 語言聲明與定義不一致導(dǎo)致的問題,歡迎閱讀。

  C 語言聲明與定義不一致導(dǎo)致的問題

  最近項目代碼需要從mips平臺移植到x86平臺,這是公司產(chǎn)品第一次采用x86平臺。之前項目很緊,所以很多代碼都沒有考慮移植性問題,因此移植的時候遇到了不少問題。前幾天才解決了位序(也叫比特序,與字節(jié)序不同)問題,今天又遇到了一個比較隱蔽的C語言問題,在這里記錄一下,告誡自己,也告誡各位同行,避免犯這樣的錯誤。至于位序問題,以后應(yīng)該會再另寫一篇文章來說明。

  原本在mips平臺上運行良好的代碼,移植到了x86平臺,結(jié)果卻不對了,我們仔細分析了代碼,沒發(fā)現(xiàn)什么可疑的地方,而且我之前為了優(yōu)化那段代碼,單獨把那段代碼抽出來測試過。我抽出來的代碼在兩個平臺里得出的都是一樣的結(jié)果。我對比了代碼,實現(xiàn)的地方?jīng)]有任何改動,照理說不應(yīng)該出現(xiàn)這種情況的。不過根據(jù)打印出來的值,我注意到了一種情況,在x86平臺里的結(jié)果值只有16位,但在mips平臺里的結(jié)果值有32位,并且低16位的值與x86平臺下的值一樣。最后,我查看了聲明該函數(shù)的頭文件,才發(fā)現(xiàn)頭文件里函數(shù)的聲明與C文件里的實現(xiàn)返回值不一致!

  問題可以簡化成下面的代碼:

  //crc.c

  //注意,此處沒有包含crc.h這個頭文件!

  unsigned int get_crc(void)

  {

  return 0x12345678;

  }

  //crc.h

  unsigned short get_crc(void);

  //main.c

  #include

  #include "crc.h"

  int main(int argc, char *argv[])

  {

  unsigned int crc = get_crc();

  printf("crc:%x ", crc);

  return 0;

  }

  編譯執(zhí)行: gcc -Wall -o test main.c crc.c //好吧,-Wall也沒辦法報錯

  在x86平臺下輸出:5678

  我又分別在mips平臺和powerpc平臺下編譯執(zhí)行了這段代碼,同樣沒警告或者報錯。在mips平臺下輸出:12345678,在powerpc平臺下輸出:12345678

  在簡化的代碼里,大家很容易就能看出是get_crc這個函數(shù)的聲明和定義(實現(xiàn))不一致導(dǎo)致的問題,但在龐大的項目文件里,可能就沒那么容易看出問題所在了。

  我們在寫代碼的時候,往往只注意函數(shù)的實現(xiàn),對函數(shù)的聲明重視不足。在Linux平臺下,我們喜歡用cscope+ctags+vim來寫代碼,修改或者瀏覽代碼的時候也喜歡跳到函數(shù)定義處,變量聲明處,卻很少關(guān)注函數(shù)聲明,導(dǎo)致修改代碼之后聲明和定義不一致的情形。

  這并不只是程序新手才會出現(xiàn)的問題,工作幾年的程序員也可能會犯這樣的錯誤,出現(xiàn)問題的這段代碼,就是出自一個已經(jīng)工作了四年的`同事之手。

  也正是在這個時候,我才發(fā)現(xiàn),我們之前的代碼是有問題的,只是所謂的“得到了正確的結(jié)果”。

  我起先認為對于這種情況,是個編譯器未定義形為,不同gcc版本對這種情況的處理可能不一樣,但我進行了一些測試,發(fā)現(xiàn)情況比我想象中的復(fù)雜。在powerpc平臺,gcc版本是3.3.x,mips平臺,gcc版本是4.3.x,在x86平臺,有兩個版本的編譯器,分別為4.1.x(centos),4,6.x(ubuntu)執(zhí)行情況是mips平臺和powerpc平臺一樣,都是12345678,x86平臺下均為5678。mips和powerpc都是大端,x86是小端,至令我沒辦法判斷真正的問題在哪,是編譯器版本原因還是與大小端有那么點關(guān)系。還望知道的朋友不吝賜教。

  此外,我還測試了對于變量的情況,發(fā)現(xiàn)對于變量的處理,各個gcc版本不同平臺都是一致的,當然,由于大小端的關(guān)系,輸出結(jié)果會不同。大家有興趣可以試一下。

  說了那么多,只是想說明這個隱蔽的錯誤大家一不小心就很容易犯,而且后果也比較嚴重,得找到方法避免。解決辦法很簡單,那就是通過把函數(shù)聲明(原型)放在頭文件中,而函數(shù)定義則放在另一個包含了該頭文件的源文件中。這樣編譯器就能發(fā)現(xiàn)不一致的情況從而報錯提醒我們。這個問題在《C專家編程》8.5節(jié)有論述。


【C 語言聲明與定義不一致導(dǎo)致的問題】相關(guān)文章:

C語言宏定義07-01

C語言函數(shù)的定義07-13

C語言變量定義07-29

C語言變量的定義與使用09-05

C語言結(jié)構(gòu)體定義06-25

C語言宏定義技巧09-03

C語言的宏定義分析09-10

C語言數(shù)組的定義及引用08-05

C語言聲明的語法04-26