解讀C++編譯報錯有跡可尋
1. 什么是編譯
1.1. 計算機程序設計語言的三個層次
在計算機系統(tǒng)中,主要有三種層次的語言,他們是機器語言、匯編語言、高級語言。
機器語言是可以被計算機理解的語言,計算機只能理解01二進制序列,但是機器語言特別難記。
匯編語言在機器語言的基礎上引入了助記符,方便記憶一些,但是要熟悉目標機器的指令特點,使用效率低,對人要求高。
正是如此引用高級語言,高級語言采用類似數(shù)學定義或者自然語言的簡潔形式,接近人的習慣并不依賴特定機器。
圖1 -1計算機程序設計語言的三個層次
1.2. 三種語言的關系
高級語言和匯編語言都要翻譯成機器語言才能在計算機上執(zhí)行,其中將高級語言轉換成匯編語言或者機器語言的過程叫做編譯,將匯編語言轉換成機器語言叫做匯編。
編譯的本質是將高級語言轉換成匯編語言或者機器語言的過程,其中高級語言就是源語言、匯編語言或機器語言就是目標語言。
2. 計算機語言處理系統(tǒng)
編譯器是計算機語言處理系統(tǒng)的核心部件,但在計算機語言處理系統(tǒng)中,除了編譯器,還有預處理器、匯編器、鏈接器。
圖2-1 計算機語言處理系統(tǒng)
預處理器的作用是把存儲在不同文件中的源程序聚合在一起;把稱為宏的縮寫語句轉換成原始語句。
編譯器的作用是把高級語言翻譯成匯編語言。
匯編器的作用是把匯編語言程序轉換成可重定向的機器代碼。可重定向的意思是匯編器所生成的這段代碼在內存中存放的開始位置不是固定的,代碼中所有地址都是相對起始地址的相對地址。起始地址+相對地址=絕對地址(內存中地址)。
鏈接器的作用是將多個可重定向的機器代碼文件(包括庫文件)鏈接在一起,也解決外部地址問題。所謂的外部地址問題是一個文件代碼引用了另外一個文件中的數(shù)據對象或者過程,那這個數(shù)據對象或者過程地址就是外部文件地址。
3. 編譯系統(tǒng)的結構
編譯系統(tǒng)的本質正是將高級語言翻譯成匯編語言或者機器語言,那么如何翻譯?
3.1. 人工翻譯英文到漢文的例子
In the room,he broke a window with a hammer.
這個英文翻譯成漢語,主要分成兩個步驟,見圖3-1。這里的源語言就是英語,目標語言就是漢語。
圖3-1 英漢翻譯的一般方法
分析過程如下:
1)找到最關鍵的謂語break。
2)然后進行主語謂語賓語的分析
圖3-2 英語句子成分劃分
3)用中間形式表示語義
圖3-3 語義表示
4)根據圖的意思用漢語翻譯
在房間里,他用錘子砸了一扇窗戶。
3.2. 語義分析過程的一點啟發(fā)
通過以上的分析,完成翻譯就是理解句子的語義,也就是語義分析。
要進行語義分析,需要知道短語的結構,需要先進行語法分析,通過語法分析劃分句子成分。句子成分是由單詞構成的,因此需要通過詞法分析獲取詞類。
一張圖解釋詞法分析,語法分析,語義分析的關系,見圖3-4。
圖3-4 詞法分析語法分析語義分析的關系
3.3. 編譯器的結構
正如前面討論的那樣子,編譯器翻譯的核心就是找到語義。實際的編譯器的結構如下3-5。
圍繞語義分析,形成前端分析部分,與源語言有關。圍繞目標語言生成構成后端綜合部分,與目標語言有關。
而語義的中間表示形式,與目標語言無關,從而與目標機器無關。
其中詞法分析器、語法分析器、語義分析器、中間代碼生成器構成編譯的核心。
圖3-5 編譯器的結構
4. 自動化編譯系統(tǒng)
在計算機語言處理系統(tǒng)中,解決了源文件和庫文件到最終的可執(zhí)行文件的過程。這個過程可以看做是一個輸入輸出系統(tǒng)。
輸入的是源文件(*.h,*.cpp)或者庫文件(*.h,*.so),輸出的是可執(zhí)行文件(*.elf)或者庫(*.so)。
對于這一過程進行輸入輸出管理的過程需要搭建自動化編譯系統(tǒng),它由make、makefile以及計算機語言處理系統(tǒng)構成。
圖4-1 自動化編譯系統(tǒng)
- Makefile作用
它保存了編譯器和鏈接器的參數(shù)選項,還表達了所有源文件之間的依賴關系。makefile關系到了整個工程的編譯規(guī)則。
一個工程中的源文件不計數(shù),其按類型、功能、模塊分別放在若干個目錄中,makefile定義了一系列的規(guī)則來指定,哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯,甚至于進行更復雜的功能操作,因為makefile就像一個Shell腳本一樣,其中也可以執(zhí)行操作系統(tǒng)的命令。
- Make作用
Make是一種程序,它首先讀取makefile文件,然后調用編譯器、匯編器、鏈接器以便產生最終的可執(zhí)行文件和庫。
5. 編譯報錯
5.1. 編譯報錯的本質
經過上述對自動化編譯系統(tǒng)的概述,以及對計算機語言處理系統(tǒng)的概述。我們可以推測編譯報錯的本質就是自動化編譯系統(tǒng)報錯,自動化編譯系統(tǒng)作為一個輸入輸出系統(tǒng),非法的輸入或者空的輸入自然會引起編譯報錯。
makefile管理整個工程的源文件和庫文件,以及計算機語言處理系統(tǒng)中的預處理器、編譯器、匯編器、鏈接器。從上述的編譯原理討論不難總結出幾個典型的編譯報錯類型:
- 輸入的makefile文件中存在makefile語法錯誤,將會導致make報錯。計算機語言處理系統(tǒng)參數(shù)設置不正確,或環(huán)境路徑錯誤將會導致make報錯。
- 輸入的源文件中存在C++語言的預處理語法錯誤,將會導致預處理器編譯報錯。
- 輸入的源文件中存在C++語言中的詞法、語法、語義錯誤,將導致編譯器報錯。
- 輸入的源文件中存在C++語言中庫使用錯誤,將導致編譯器報錯。
- 輸入的庫文件和源文件存在C++語言中的語法錯誤,導致鏈接器報錯?;蛘咻斎氲膸煳募驮次募嬖诃h(huán)境路徑錯誤,將導致鏈接器報錯。
5.2. makefile報錯
- Makefile語法錯誤
- 編譯器參數(shù)設置錯誤
5.3. 預處理報錯
- C++宏定義錯誤
5.4. 源程序編譯報錯
- C++詞法錯誤
- C++語法錯誤
- C++語義錯誤
- C++的類庫使用錯誤
5.5. 庫鏈接報錯
- C++語法錯誤
- 庫頭文件與庫本身不匹配錯誤
5.6. 其他錯誤
- 路徑配置錯誤
- 文件權限獲取錯誤
- 源文件未及時保存錯誤
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
C/C++?Qt?選擇夾TabWidget組件實現(xiàn)導航欄切換
Tab切換在很多地方都可以使用的到,本文就使用TabWidget組件來實現(xiàn)一下,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11C++下如何將TensorFlow模型封裝成DLL供C#調用
這篇文章主要介紹了C++下如何將TensorFlow模型封裝成DLL供C#調用問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11