了解C++编译

Cha*_*son 4 c++ ide compiler-errors header build-system

我最近意识到,从通用角度来说,我不知道ac/c ++编译器是如何工作的.我会承认这最初来自于试图理解标题保护,但我意识到我缺乏编译工作.

以Visual C++为例; 有"Header Files"文件夹,"Resources Files"文件夹和"Source Files"文件夹.这些文件夹的分离和放在它们中的内容有什么意义吗?对我来说,它们都是源文件.拿代码片段:

片段1

//a1.h
int r=4;
Run Code Online (Sandbox Code Playgroud)

//a1.cpp
int b  //<--semicolon left out on purpose
Run Code Online (Sandbox Code Playgroud)

//main.cpp
#include <iostream>
#include "a1.h"
void main()
{
   cout << r;
}
Run Code Online (Sandbox Code Playgroud)

编译器错误地说"a1.cpp(3):致命错误C1004:发现意外的文件结尾"我认为它不会因为a1.cpp文件不是#included主要方法存在于哪里下一个代码段

片段2

//a1.h
int r=4 //<--semicolon left out on purpose
Run Code Online (Sandbox Code Playgroud)

//a1.cpp
int b = 4;  
Run Code Online (Sandbox Code Playgroud)

//main.cpp
#include <iostream>
void main()
{
   cout << b;
}
Run Code Online (Sandbox Code Playgroud)

错误,因为"main.cpp(6):错误C2065:'b':未声明的标识符".如果像这样包含a1.cpp

代码段3

//a1.h
int r=4 //<--semicolon left out on purpose
Run Code Online (Sandbox Code Playgroud)

//a1.cpp
int b = 4;  
Run Code Online (Sandbox Code Playgroud)

//main.cpp
#include <iostream>
#include "a1.cpp"
void main()
{
   cout << b;
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨"a1.obj:错误LNK2005:"int b"(?b @@ 3HA)已在main.obj中定义".片段2和3都忽略了int r = 4没有分号丢失的事实,因为我怀疑它与xxxx.h文件有关.如果我从代码片段1中的项目中删除a1.cpp文件,那么它编译得很好.显然我所期待的不是我得到的.有很多关于如何在cpp中编码的书籍和教程,但cpp在complition过程中处理文件和源代码的方式并不多.这到底是怎么回事?

Car*_*rum 6

您的问题不是关于编译器,而是关于IDE如何处理整个构建系统.大多数C/C++项目的构建系统分别编译每个文件.c.cpp文件,然后将生成的目标文件链接到最终的可执行文件中.在您的情况下,IDE正在编译项目中文件扩展名为的所有文件.cpp,然后链接生成的对象.您所看到的行为可以解释如下:

  1. a1.cpp缺少一个;,所以当IDE尝试编译该文件时,您会收到有关"意外结束文件"的错误.

  2. b未在main.cpp编译单元中的任何位置声明,因此您会收到有关未定义标识符的错误.

  3. b存在于两个main.cppa1.cpp编译单元(明显a1.cpp,并通过您#includemain.cpp).你的IDE编译这两个文件的-现在a1.omain.o每一个都包含称为对象b.链接时,会出现重复的符号错误.

这里带走的重点是解释您看到的所有行为,即IDE会编译每个 .cpp文件 - 不仅仅是main.cpp文件及其包含的文件 - 然后链接生成的对象.

我建议使用您自己创建的makefile设置命令行测试项目 - 这将教您构建系统的内部工作,然后您可以将这些知识应用于IDE的内部工作.