一種KEIL中定義過的變量在使用中提示未定義的情況


【環境】

  > KEIL5.25

  > win10

  > @2018-4-23 

 

【問題】

頭文件互包含導致的錯誤(使用了另一文件的類型定義)

文件<fileA.h>

 1 <fileA.h>
 2 
 3 #ifndef    __FILEA_H__
 4 #define    __FILEA_H__
 5 
 6 #include "fileB.h"
 7 
 8 typedef struct
 9 {
10     int var;
11 }stuct_A_s;
12 
13 
14 #endif

 

文件<fileB.h>

 1 <fileB.h>
 2 
 3 #ifndef    __FILEB_H__
 4 #define    __FILEB_H__
 5  
 6 #include "fileA.h"
 7 
 8 typedef struct
 9 {
10     int var;
11     struct_A_s obj;
12 }struct_B_s;
13 
14 #endif

 

編譯后報錯:在文件<fileB.h>中   error:  #20: identifier "struct_A_s" is undefined  

【分析】

導致上述錯誤的原因,是在文件<fileA.h>中,使用了 fileB.h,而文件<fileB.h>中使用的類  struct_A_s 在其定義之前,故產生了先使用后定義的語法錯誤

具體分析:

  從文件<fileA.h>開始分析:

  > 執行避免頭文件重復包含的宏 --- <fileA.h>

  > 包含文件<fileB.h>,進入文件<fileB.h>

  > 執行避免頭文件重復包含的宏 --- <fileB.h>

  > 包含文件<fileA.h>,進入文件<fileA.h>

  > 由於避免重復包含宏的控制,進不去A文件內容部分,跳轉回文件<fileB.h>

  > 執行結構體 struct_B_s 定義,結構體成員類型使用了結構體 struct_A_s ,這就出現了使用了未定義的情況,執行完畢跳轉回文件<fileA.h>

  > 執行結構體 struct_A_s 定義,結合上一步就發生了先使用后定義的問題,執行完畢結束

  結論:編譯器先從文件<fileA.h>開始編譯就會出現本文所示錯誤

 

  從文件<fileB.h>開始分析:

  > 執行避免頭文件重復包含的宏 --- <fileB.h>

  > 包含文件<fileA.h>,進入文件<fileA.h>

  > 執行避免頭文件重復包含的宏 --- <fileA.h>

  > 包含文件<fileB.h>,進入文件<fileB.h>

  > 由於避免重復包含宏的控制,進不去B文件內容部分,跳轉回文件<fileA.h>

  > 執行結構體 struct_A_s 定義,執行完畢跳轉回文件<fileB.h>

  > 執行結構體 struct_B_s 定義,執行完畢結束

  結論:編譯器先從文件<fileB.h>開始編譯就不會報錯誤

 

【解決】

  # 去除文件<fileA.h>中包含文件<fileB.h>的語句部分,可解決此問題

  # 由於分析推出是編譯順序導致錯誤的出現,特做了一下一些事做實驗:

    > 控制文件 <fileA.h> 與 <fileB.h> 的編譯順序  (做了文件名的更改,即按照字母表順序修改文件名達到兩次編譯時兩個文件的排序相異)

    > 兩次編譯的結果都是報相同的錯誤,error:  #20: identifier "struct_A_s" is undefined  

【結論】

  # 綜上暫推出,編譯器在編譯時,每個文件都會單獨編譯一遍,所以不論文件 <fileA.h> 與 <fileB.h> 的排序,都會出現相同的問題

  # 一般是杜絕文件互相包含的,因為文件包含的意義就是要使用被包含文件的一些定義,互相包含就會出現先使用后定義 的情況發生

  # 了解一些編譯原理的知識后,將會得到更權威的解惑,以上只是根據現象分析的結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM