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