在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

編譯器怎么處理同名頭文件

嵌入式軟件實戰派 ? 來源:嵌入式軟件實戰派 ? 2024-11-05 16:51 ? 次閱讀

C語言中的include很簡單,但不是你想象中的簡單。

之前寫過一個《C語言的include沒你想的那么簡單》,廣受大家喜愛,詳見《C語言的include沒你想的那么簡單(圖文版)》或《C語言的Include沒你想的那么簡單(視頻版)》。

最近又遇到個新問題,對于同名頭文件,編譯器是怎么處理的?

我這個踩坑過程就不細說了,說多了都是淚,直接上干貨吧!

如果你嫌我啰嗦,你就直接拖到文末看截圖的結果匯總吧!

為了講清楚這個問題,我做了個實驗,編了個這樣的目錄結構和文件:

./
│  main.c
│
├─inc1
│      inc.h
│      inc1.c
│
└─inc2
        inc.h
而這些文件內容分別如下: (1)./main.c
// ./main.c
#include 
#include "inc.h"


extern int inc1(void);


int main(void)
{
    printf("main VAL=%d
",VAL);
    printf("inc1 VAL=%d
",inc1());


    return 0;
}
(2)./inc1/inc.h
// ./inc1/inc.h
#ifndef _INC_H_
#define _INC_H_
  #pragma message(__FILE__)
  #define VAL 1
#endif
(3)./inc1/inc1.c
// ./inc1/inc1.c
#include "inc.h"
int inc1(void)
{
    return VAL;
}
(4)./inc2/inc.h
//./inc2/inc.h
#ifndef _INC_H_
#define _INC_H_
  #pragma message(__FILE__)
  #define VAL 2
#endif
然后,我分別用Cygwin上的GCC、Linux上的GCC、Window上的GreenHills和Windows上的ARMCC做了測試。 首先,直接在Windows上的命令窗口上直接執行(基于Cygwin上的GCC):
gcc .main.c.inc1inc1.c-omain
得到的是
.main.c:2:10: fatal error: inc.h: No such file or directory
    2 | #include "inc.h"
      |          ^~~~~~~
compilation terminated.
.inc1inc1.c:1:10: fatal error: inc.h: No such file or directory
    1 | #include "inc.h"
      |          ^~~~~~~
compilation terminated.

你會發現有兩個錯誤,.main.c里面的inc.h找不到還好理解,但是.inc1inc1.c里面的inc.h也找不到?跟inc1.c同級的目錄下有一個inc.h啊?!
接下來,通過編譯選項-I(指定頭文件路徑)加入頭文件路徑看看。
 gcc .main.c .inc1inc1.c -Iinc1 -Iinc2 -o main
得到的是
In file included from .main.c:2:
inc1/inc.h:3:11: note: '#pragma message: inc1/inc.h'
    3 |   #pragma message(__FILE__)
      |           ^~~~~~~
In file included from .inc1inc1.c:1:
inc1/inc.h:3:11: note: '#pragma message: inc1/inc.h'
    3 |   #pragma message(__FILE__)
      |           ^~~~~~~

兩個地方認的都是inc1/inc.h。可以理解,-Iinc1 -Iinc2哪個先就用哪個。
接著,只指定-Iinc2,看看什么效果
 gcc .main.c .inc1inc1.c -Iinc2 -o main
得到的是
Infileincludedfrom.main.c:2:
inc2/inc.h:3:11: note: '#pragma message: inc2/inc.h'
  3 |  #pragma message(__FILE__)
   |      ^~~~~~~
In file included from .inc1inc1.c:1:
inc2/inc.h:3:11: note: '#pragma message: inc2/inc.h'
  3 |  #pragma message(__FILE__)
|^~~~~~~

好家伙,兩個地方都認的是inc2/inc.h!.inc1inc1.c為什么不要它旁邊的inc1/inc.h呢?

難道通過-I指定路徑的優先級是最高的?接下來,通過-I指定一個空路徑試試。
gcc.main.c.inc1inc1.c-I-Iinc1-Iinc2-o main

得到的是

In file
included from .main.c:2:
inc2/inc.h:3:11:
note: '#pragma message: inc2/inc.h'
 3 |  #pragma message(__FILE__)
 |           ^~~~~~~
In file
included from .inc1inc1.c:1:
inc2/inc.h:3:11:
note: '#pragma message: inc2/inc.h'
 3 |  #pragma message(__FILE__)
 |           ^~~~~~~

看清楚這里哦-I-Iinc1-Iinc2,按剛才的推測,-I的優先級是最高的,但是這個-I是什么路徑?導致最終用的頭文件是inc2/inc.h??

不行,再來一發,將-I改為-I./,這樣又會怎樣呢?
gcc .main.c .inc1inc1.c -I./ -Iinc1 -Iinc2 -o main

?

得到的是

Infileincludedfrom.main.c:2:
inc1/inc.h:3:11: note: '#pragma message: inc1/inc.h'
    3 |   #pragma message(__FILE__)
      |           ^~~~~~~
In file included from .inc1inc1.c:1:
inc1/inc.h:3:11: note: '#pragma message: inc1/inc.h'
    3 |   #pragma message(__FILE__)
      |           ^~~~~~~
凌亂了吧,-I和-I./是不一樣的?!

等等,是不是Windows這“/”和“”不一樣,Powershell和Cygwin雜交就不一樣了?? 于是,我找了個純血的Linux+GCC試試。把路徑中的換成/:

gcc ./main.c./inc1/inc1.c-omain

./main.c:2
fatal error: inc.h: No such file or directory
 2 | #include "inc.h"
 |         ^~~~~~~
compilation
terminated.
In file
included from ./inc1/inc1.c
./inc1/inc.h:3
note: '#pragma message: ./inc1/inc.h'
 3 |  #pragma message(__FILE__)
 |           ^~~~~~~

果真,對比上面第一個案例,這里只提示一個錯誤,說明如果不用-I指定頭文件,編譯器是可以就近找到當前路徑的頭文件的。
接下來,再看一個例子
gcc ./main.c./inc1/inc1.c-Iinc2-omain
In file
included from ./main.c:2:
inc2/inc.h:3:11:
note: '#pragma message: inc2/inc.h'
 3 |  #pragma message(__FILE__)
 |           ^~~~~~~
In file
included from ./inc1/inc1.c:1:
./inc1/inc.h:3:11:
note: '#pragma message: ./inc1/inc.h'
 3 |  #pragma message(__FILE__)
 |           ^~~~~~~

這里說明,并不是-Iinc2指定的優先級是最高的,./inc1/inc1.c還是能找到最近的頭文件./inc1/inc.h。

這說明什么呢?不知道,不好說,反正我就不相信網上說的那些,我只相信實驗出來的結果。

小平同志說過:實踐是檢驗真理的唯一標準!

那么,我就用我電腦上的其他幾個編譯器(Greenhills里的CCRH850、S32DS里的ARMCC),全部搞一遍,做個對比。我用紅框把異類標出來了: b45dae76-90b5-11ef-a511-92fbcf53809c.png

然后,有什么規律呢,自己總結哈!我是不記這些的,寫幾個代碼試試就知道結果了。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7614

    瀏覽量

    137716
  • 編譯器
    +關注

    關注

    1

    文章

    1642

    瀏覽量

    49286
  • 頭文件
    +關注

    關注

    0

    文章

    25

    瀏覽量

    9901

原文標題:C語言的include沒你想的那么簡單(同名問題)

文章出處:【微信號:embedded_sw,微信公眾號:嵌入式軟件實戰派】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    【Makefile】C文件包含的頭文件修改,但不重新編譯

    【Linux + Makefile】Makefile的高階用法:解決C文件包含的頭文件修改了,但C文件不重新編譯的問題!
    的頭像 發表于 09-08 08:53 ?5537次閱讀
    【Makefile】C<b class='flag-5'>文件</b>包含的<b class='flag-5'>頭文件</b>修改,但不重新<b class='flag-5'>編譯</b>?

    求助,COSMIC編譯器頭文件IOSTM8.H的相關問題求解

    我的時鐘CLK_ICKR在兩個頭文件中不一樣,我沒更改過頭文件,這是什么情況呢?請大家說說 RM0016中的名字是:CLK_ICKR iostm8.h中的名字是:CLK_ICKR iostm8s.h中名字是:CLK_ICKCR(錯誤) 但
    發表于 04-28 06:21

    盛群ht-ide3000編譯器怎么添加自己編的頭文件

    使用盛群公司的ht-ide3000編譯器時,由于在程序中使用了數學函數等等,需要包含等頭文件,但是我在工程下面的在頭文件中包含該文件后,編譯器
    發表于 04-03 23:42

    XC8編譯器頭文件定義

    本人新手,想請教論壇中PIC編程高手幾個問題,關于XC8編譯器頭文件定義的。僅有8分全奉獻了。1、這個條件匯編是什么意思?具體_LIB_BUILD是什么意思?#ifndef
    發表于 01-22 14:25

    C 18編譯器頭文件問題

    當我試圖在C 18編譯器中包含頭文件時。它在頭文件末尾引發語法錯誤。
    發表于 04-10 09:19

    Bat 文件編譯器

    Bat 文件編譯器匯編語言源程序代碼:; BAT2EXEC.COM - a batch file compiler;; BAT2EXEC filename;; Revision
    發表于 05-06 16:42 ?6次下載

    STC單片機在KEIL編譯器中的頭文件

    STC單片機在keil編譯器里找不到頭文件如何處理。首先在網絡上找到一個關于STC單片機的升級包。安裝上去以后,就可以看到有STC型號的單片機可以選擇了。但是此時,它的頭文件卻無法
    發表于 08-26 10:52 ?8293次閱讀

    C語言中程序員編寫的頭文件編譯器自帶的頭文件

    #include 指令會指示 C 預處理器瀏覽指定的文件作為輸入。預處理器的輸出包含了已經生成的輸出,被引用文件生成的輸出以及 #include 指令之后的文本輸出。例如,如果您
    的頭像 發表于 11-12 14:55 ?7893次閱讀

    ASM源文件編譯器軟件免費下載

    本文檔的主要內容詳細介紹的是ASM源文件編譯器軟件免費下載。適用于32位計算機,asm編譯器,將ASM51.exe放在同一目錄,在dos狀態編譯 如; d:asm51.exe ***.
    發表于 08-07 08:00 ?6次下載
    ASM源<b class='flag-5'>文件</b><b class='flag-5'>編譯器</b>軟件免費下載

    編程中引用頭文件的幾種方法及要點

    《》 #include使用引號“” 還是 尖括號《》 這個是有規定的。 通常來說:系統自帶的頭文件用尖括號括起來,這樣編譯器會在系統文件目錄下查找。 #include 《xxx.h》 用戶自定義的
    的頭像 發表于 03-12 17:30 ?3419次閱讀

    Verilog HDL 編譯器指令說明

    編譯時,特定的編譯器指令在整個編譯過程中有效(編譯過程可跨越多個文件),直到遇到其它的不同編譯
    的頭像 發表于 11-03 09:31 ?3864次閱讀
    Verilog HDL <b class='flag-5'>編譯器</b>指令說明

    編譯器將.c文件編譯為.o文件鏈接的過程

    對大多數童鞋來說理解編譯器將.c文件編譯為.o文件并不大困難,但是卻難以明白最后鏈接的過程是什么作用和為什么要這樣做?
    的頭像 發表于 10-13 09:36 ?5044次閱讀

    C語言頭文件路徑的剖析

    編譯器編譯過程中會按照這些路徑信息到指定的位置去查找頭文件,然后通過預處理器作展開處理。在查找頭文件
    的頭像 發表于 02-17 09:44 ?1947次閱讀
    C語言<b class='flag-5'>頭文件</b>路徑的剖析

    Triton編譯器功能介紹 Triton編譯器使用教程

    。以下是 Triton 編譯器的一些功能介紹和使用教程。 Triton 編譯器功能介紹 多語言支持 :Triton 支持多種編程語言,使得開發者可以在同一個編譯器框架下處理不同的語言。
    的頭像 發表于 12-24 17:23 ?641次閱讀

    Triton編譯器與其他編譯器的比較

    Triton編譯器與其他編譯器的比較主要體現在以下幾個方面: 一、定位與目標 Triton編譯器 : 定位:專注于深度學習中最核心、最耗時的張量運算的優化。 目標:提供一個高度抽象、靈活、高效
    的頭像 發表于 12-24 17:25 ?484次閱讀
    主站蜘蛛池模板: 色多多福利网站老司机 | 亚色成人| 操你啦网站 | 久久久久九九精品影院 | 午夜美女网站 | 深爱婷婷 | 美女拍拍拍免费视频观看 | 国产一区二区三区美女在线观看 | 五月婷婷婷 | 日本韩国做暖暖小视频 | 五月激情综合网 | 无毒不卡在线观看 | 一级a爱片久久毛片 | 中文字幕一区二区三区有限公司 | 亚洲乱码一二三四区 | 四虎影视永久地址 | 色香色香欲天天天影视综合网 | 新版天堂资源中文在线 | 一区二区三区四区精品 | 免费黄色大片网站 | 欧美日韩一日韩一线不卡 | www天堂网| 亚洲男人的性天堂 | 亚洲国产精品婷婷久久久久 | 五月婷婷网址 | 天天操天天摸天天爽 | 日本a级片在线观看 | 农村女人的一级毛片 | 国产黄色录像视频 | 你懂的免费在线视频 | 欧美日韩国产乱了伦 | 爱爱免费小视频 | 操到喷水| 特黄特级高清免费视频毛片 | 国产精品久久久久免费 | 免费日韩一级片 | 国产产一区二区三区久久毛片国语 | 干干操| 日韩一级在线视频 | 四虎在线永久免费观看 | 亚洲黄色三级网站 |