解读C++编译报错有迹可寻

 更新时间:2023年05月08日 17:09:36   作者:111尽力而为  
这篇文章主要介绍了解读C++编译报错有迹可寻,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

1. 什么是编译

1.1. 计算机程序设计语言的三个层次

在计算机系统中,主要有三种层次的语言,他们是机器语言、汇编语言、高级语言。

机器语言是可以被计算机理解的语言,计算机只能理解01二进制序列,但是机器语言特别难记。

汇编语言在机器语言的基础上引入了助记符,方便记忆一些,但是要熟悉目标机器的指令特点,使用效率低,对人要求高。

正是如此引用高级语言,高级语言采用类似数学定义或者自然语言的简洁形式,接近人的习惯并不依赖特定机器。

图1 -1计算机程序设计语言的三个层次

1.2. 三种语言的关系

高级语言和汇编语言都要翻译成机器语言才能在计算机上执行,其中将高级语言转换成汇编语言或者机器语言的过程叫做编译,将汇编语言转换成机器语言叫做汇编。

编译的本质是将高级语言转换成汇编语言或者机器语言的过程,其中高级语言就是源语言、汇编语言或机器语言就是目标语言。

2. 计算机语言处理系统

编译器是计算机语言处理系统的核心部件,但在计算机语言处理系统中,除了编译器,还有预处理器、汇编器、链接器。

图2-1 计算机语言处理系统

预处理器的作用是把存储在不同文件中的源程序聚合在一起;把称为宏的缩写语句转换成原始语句。

编译器的作用是把高级语言翻译成汇编语言。

汇编器的作用是把汇编语言程序转换成可重定向的机器代码。可重定向的意思是汇编器所生成的这段代码在内存中存放的开始位置不是固定的,代码中所有地址都是相对起始地址的相对地址。起始地址+相对地址=绝对地址(内存中地址)。

链接器的作用是将多个可重定向的机器代码文件(包括库文件)链接在一起,也解决外部地址问题。所谓的外部地址问题是一个文件代码引用了另外一个文件中的数据对象或者过程,那这个数据对象或者过程地址就是外部文件地址。

3. 编译系统的结构

编译系统的本质正是将高级语言翻译成汇编语言或者机器语言,那么如何翻译?

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. 语义分析过程的一点启发

通过以上的分析,完成翻译就是理解句子的语义,也就是语义分析。

要进行语义分析,需要知道短语的结构,需要先进行语法分析,通过语法分析划分句子成分。句子成分是由单词构成的,因此需要通过词法分析获取词类。

一张图解释词法分析,语法分析,语义分析的关系,见图3-4。

图3-4 词法分析语法分析语义分析的关系 

3.3. 编译器的结构

正如前面讨论的那样子,编译器翻译的核心就是找到语义。实际的编译器的结构如下3-5。

围绕语义分析,形成前端分析部分,与源语言有关。围绕目标语言生成构成后端综合部分,与目标语言有关。

而语义的中间表示形式,与目标语言无关,从而与目标机器无关。

其中词法分析器、语法分析器、语义分析器、中间代码生成器构成编译的核心。

图3-5 编译器的结构 

4. 自动化编译系统

在计算机语言处理系统中,解决了源文件和库文件到最终的可执行文件的过程。这个过程可以看做是一个输入输出系统。

输入的是源文件(*.h,*.cpp)或者库文件(*.h,*.so),输出的是可执行文件(*.elf)或者库(*.so)。

对于这一过程进行输入输出管理的过程需要搭建自动化编译系统,它由make、makefile以及计算机语言处理系统构成。

 图4-1 自动化编译系统

  • Makefile作用

它保存了编译器和链接器的参数选项,还表达了所有源文件之间的依赖关系。makefile关系到了整个工程的编译规则。

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

  • Make作用

Make是一种程序,它首先读取makefile文件,然后调用编译器、汇编器、链接器以便产生最终的可执行文件和库。

5. 编译报错

5.1. 编译报错的本质

经过上述对自动化编译系统的概述,以及对计算机语言处理系统的概述。我们可以推测编译报错的本质就是自动化编译系统报错,自动化编译系统作为一个输入输出系统,非法的输入或者空的输入自然会引起编译报错。

makefile管理整个工程的源文件和库文件,以及计算机语言处理系统中的预处理器、编译器、汇编器、链接器。从上述的编译原理讨论不难总结出几个典型的编译报错类型:

  • 输入的makefile文件中存在makefile语法错误,将会导致make报错。计算机语言处理系统参数设置不正确,或环境路径错误将会导致make报错。
  • 输入的源文件中存在C++语言的预处理语法错误,将会导致预处理器编译报错。
  • 输入的源文件中存在C++语言中的词法、语法、语义错误,将导致编译器报错。
  • 输入的源文件中存在C++语言中库使用错误,将导致编译器报错。
  • 输入的库文件和源文件存在C++语言中的语法错误,导致链接器报错。或者输入的库文件和源文件存在环境路径错误,将导致链接器报错。

5.2. makefile报错

  • Makefile语法错误
  • 编译器参数设置错误

5.3. 预处理报错

  • C++宏定义错误

5.4. 源程序编译报错

  • C++词法错误
  • C++语法错误
  • C++语义错误
  • C++的类库使用错误

5.5. 库链接报错

  • C++语法错误
  • 库头文件与库本身不匹配错误

5.6. 其他错误

  • 路径配置错误
  • 文件权限获取错误
  • 源文件未及时保存错误

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • (C和指针) #if 0/#if 1...#end if

    (C和指针) #if 0/#if 1...#end if

    #if 0还有一个重要的用途就是用来当成注释,如果你想要注释的程序很长,这个时候#if 0是最好的,保证不会犯错误
    2013-09-09
  • C++ 继承详解及实例代码

    C++ 继承详解及实例代码

    这篇文章主要介绍了C++ 继承详解,这里整理了详细的资料及实例代码,有需要的小伙伴可以参考下
    2016-09-09
  • C/C++ Qt 选择夹TabWidget组件实现导航栏切换

    C/C++ Qt 选择夹TabWidget组件实现导航栏切换

    Tab切换在很多地方都可以使用的到,本文就使用TabWidget组件来实现一下,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C++下如何将TensorFlow模型封装成DLL供C#调用

    C++下如何将TensorFlow模型封装成DLL供C#调用

    这篇文章主要介绍了C++下如何将TensorFlow模型封装成DLL供C#调用问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C/C++ 公有继承、保护继承和私有继承的对比详解

    C/C++ 公有继承、保护继承和私有继承的对比详解

    这篇文章主要介绍了C/C++ 公有继承、保护继承和私有继承的区别的相关资料,需要的朋友可以参考下
    2017-02-02
  • wxWidgets实现无标题栏窗口拖动效果

    wxWidgets实现无标题栏窗口拖动效果

    这篇文章主要为大家详细介绍了wxWidgets实现无标题栏窗口拖动效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • 深入理解void以及void指针的含义

    深入理解void以及void指针的含义

    本篇文章对小编void以及void指针的含义进行了详细的分析和介绍。需要的朋友参考下
    2013-05-05
  • C语言深入探索动态内存分配的使用

    C语言深入探索动态内存分配的使用

    给数组分配多大的空间?你是否和初学C时的我一样,有过这样的疑问。这一期就来聊一聊动态内存的分配,读完这篇文章,你可能对内存的分配有一个更好的理解
    2022-04-04
  • C语言实现ATM机存取款系统

    C语言实现ATM机存取款系统

    这篇文章主要为大家详细介绍了C语言实现ATM机存取款系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C语言编写Linux守护进程实例

    C语言编写Linux守护进程实例

    这篇文章主要介绍了C语言编写Linux守护进程实例,本文讲解了守护进程及其特性、守护进程的编程要点、守护进程代码实例等内容,需要的朋友可以参考下
    2015-02-02

最新评论