C++编译与文件大小

C++编译与文件大小,c++,c++11,compiler-construction,compilation,filesize,C++,C++11,Compiler Construction,Compilation,Filesize,我在谷歌上搜索过这个,但大多数结果都是关于编译器A和编译器B的 这个问题源于我在网页设计方面的经验,我知道网页设计中常用的语言并没有被编译。CGI是一个例外。在网页中包含文件时,整个文件将下载到用户的计算机上。如果使用JQuery(一个JavaScript库),则必须在中包含JQuery才能使用其函数。这让我想到C++编译器。 在C++中,不含包含程序几乎是不可能的。库是否与项目文件一起编译?是 例如,在这个简单的Hello Word程序include中,是否编译了iostream头文件中的所有

我在谷歌上搜索过这个,但大多数结果都是关于编译器A和编译器B的

这个问题源于我在网页设计方面的经验,我知道网页设计中常用的语言并没有被编译。CGI是一个例外。在网页中包含文件时,整个文件将下载到用户的计算机上。如果使用JQuery(一个JavaScript库),则必须在中包含JQuery才能使用其函数。这让我想到C++编译器。

在C++中,不含包含程序几乎是不可能的。库是否与项目文件一起编译?是

例如,在这个简单的Hello Word程序include中,是否编译了iostream头文件中的所有代码?仅使用定义cout的代码并将其添加到此示例中会使文件的大小变小吗?编译器优化是否只考虑从iostream编译必要的代码


图书馆是预先编译的。您的程序与库相链接。类似运行时C++的LIB < /P> 如果您使用的是静态库,链接器将把使用的方法复制到您的可执行文件中

如果您使用的是共享库so、DLL等,它会将可执行文件中的引用保存到链接的方法中,而不是保存到可执行文件中

包含文件不是预编译的。它们包含一些类或库的API。通常只有方法的原型,但有时像模板类中的所有源代码 使用include宏意味着将整个头文件复制到源文件中

更重要的是,编译过程中有一些步骤:

预处理-将所有包含文件添加到位。宏解析等。输出是一个更大的源文件,可以编译。 编译-将每个源文件编译为机器语言,输出二进制文件和目标文件 链接-获取所有编译文件和所有使用的库并生成可执行文件。
编译器编译所有源代码,但在链接中,链接器只获取使用过的代码并将其添加到可执行文件中,无论代码是在源代码的头中还是在库中。如果未使用,则不会将其添加到可执行文件中。

库是预编译的。您的程序与库相链接。类似运行时C++的LIB < /P> 如果您使用的是静态库,链接器将把使用的方法复制到您的可执行文件中

如果您使用的是共享库so、DLL等,它会将可执行文件中的引用保存到链接的方法中,而不是保存到可执行文件中

包含文件不是预编译的。它们包含一些类或库的API。通常只有方法的原型,但有时像模板类中的所有源代码 使用include宏意味着将整个头文件复制到源文件中

更重要的是,编译过程中有一些步骤:

预处理-将所有包含文件添加到位。宏解析等。输出是一个更大的源文件,可以编译。 编译-将每个源文件编译为机器语言,输出二进制文件和目标文件 链接-获取所有编译文件和所有使用的库并生成可执行文件。 编译器编译所有源代码,但在链接中,链接器只获取使用过的代码并将其添加到可执行文件中,无论代码是在源代码的头中还是在库中。如果没有使用它,它将不会被添加到可执行文件中。

像iostream这样的头文件定义了各种类型、函数,有时还定义了全局文件

库文件是实现头文件的函数/类的预编译源代码。cout在头文件中定义,但驻留在库中。

像iostream这样的头文件定义了各种类型、函数,有时还定义了全局变量


库文件是实现头文件的函数/类的预编译源代码。cout在头文件中定义,但驻留在库中。

通常,编译器确保只添加程序运行所需的代码位。然而,在有些情况下,include确实会使代码变大。一种情况是,如果库使用的内联代码确实增加了大小。

通常,编译器确保只添加程序运行所需的代码位。然而,在有些情况下,include确实会使代码变大。一种情况是,如果库使用内联代码,则会增加大小。

所有编译器都有自己的STL实现——有些是开源gcc,有些只包含头。在大多数情况下,这些实现被编译到一个库中,以加快程序的编译过程。这些头文件只是向编译器提示这些已编译库包含的内容,有点像阅读库内容的指南。它们不是自己编译的

如果此库是静态的,则链接 er阶段从库中获取数据并将其复制到可执行文件中。如果它是一个动态库.dll、.so或.dylib,那么就不会复制任何数据——您的可执行文件只在运行时调用这些文件中的数据。这可能是通过函数地址或符号名称实现的,具体取决于动态库的链接方式。在大多数情况下,动态库是前者


编译器有一个优化阶段,可以去除未使用的数据。例如,如果您包括iostream,但没有使用它的任何内容,那么这些数据都不会链接到您的程序。根据编译器的不同,如果只使用cout::operator的一个重载,那么所有编译器都有自己的STL实现——有些是开源gcc,有些只包含头。在大多数情况下,这些实现被编译到一个库中,以加快程序的编译过程。这些头文件只是向编译器提示这些已编译库包含的内容,有点像阅读库内容的指南。它们不是自己编译的

如果此库是静态的,则链接器阶段从库中获取数据并将其复制到可执行文件中。如果它是一个动态库.dll、.so或.dylib,那么就不会复制任何数据——您的可执行文件只在运行时调用这些文件中的数据。这可能是通过函数地址或符号名称实现的,具体取决于动态库的链接方式。在大多数情况下,动态库是前者

编译器有一个优化阶段,可以去除未使用的数据。例如,如果您包括iostream,但没有使用它的任何内容,那么这些数据都不会链接到您的程序。根据编译器的不同,如果只使用cout::operator的一个重载 例如,在这个简单的Hello Word程序include中,是否编译了iostream头文件中的所有代码?仅使用定义cout的代码并将其添加到此示例中是否会减小文件的大小?编译器优化是否只考虑从iostream编译必要的代码

是,C++是一个非常简单的机制。included头实际上只是与included文件连接在一起,所以是的,简单的答案是您得到了所有包含的内容

但一旦以这种方式包含了所有内容,编译器就会尝试消除所有未使用的位。对于许多并非所有的头文件,这很容易观察到:如果编译一个简单的Hello World程序,查看文件大小,然后再包含几个头文件并重新编译,可执行文件的大小通常会相同或几乎相同。编译器确定您包含的大部分积垢从未使用过,并再次将其删除

但也有例外。例如,某些头文件仅仅被包含,就导致在启动应用程序时运行代码,这意味着即使您没有引用头文件中包含的任何内容,编译器也无法删除它

例如,在这个简单的Hello Word程序include中,是否编译了iostream头文件中的所有代码?仅使用定义cout的代码并将其添加到此示例中是否会减小文件的大小?编译器优化是否只考虑从iostream编译必要的代码

是,C++是一个非常简单的机制。included头实际上只是与included文件连接在一起,所以是的,简单的答案是您得到了所有包含的内容

但一旦以这种方式包含了所有内容,编译器就会尝试消除所有未使用的位。对于许多并非所有的头文件,这很容易观察到:如果编译一个简单的Hello World程序,查看文件大小,然后再包含几个头文件并重新编译,可执行文件的大小通常会相同或几乎相同。编译器确定您包含的大部分积垢从未使用过,并再次将其删除


但也有例外。例如,某些头文件仅仅被包含,就导致在启动应用程序时运行代码,这意味着即使您没有引用头文件中包含的任何内容,编译器也无法将其删除。

错误在于您将头文件视为库。检查一下,找到一本关于C++的入门书。@ iTestTobe,当我措辞错误时,我想我看到了。iostream是标准模板库的一部分,对吗?我还没有读过标准模板库;它在书的后面。@ CLSIs是C++标准库的一部分。STL是一个模糊的术语,但通常来说,谈论标准库更为正确。STL最初是一个单独的库,基本上由容器、迭代器和算法组成,但被并入C++标准库中。标题,`和各种容器,如和,都是以这种方式来自STL的。但是没有。在STL和

它的年龄表明。与STL相关的东西相比,它是一个可怕的API。所以,STL是C++标准库的一部分,但是C++标准LIB也包含了很多其他的部分。@ CursS:如果你的书直到最后才提到STL,那么你就有一本糟糕的书。错误是你把页眉当作图书馆。检查一下,找到一本关于C++的入门书。@ iTestTobe,当我措辞错误时,我想我看到了。iostream是标准模板库的一部分,对吗?我还没有读过标准模板库;它在书的后面。@ CLSIs是C++标准库的一部分。STL是一个模糊的术语,但通常来说,谈论标准库更为正确。STL最初是一个单独的库,基本上由容器、迭代器和算法组成,但被并入C++标准库中。标题,`和各种容器,如和,都是以这种方式来自STL的。但是没有。它在STL和它的年龄显示之前就在那里。与STL相关的东西相比,它是一个可怕的API。所以,STL是C++标准库的一部分,但是C++标准LIB也包含了很多其他的部分。@ CursS:如果你的书没有提到STL直到最后,那么你就有一本糟糕的书。这就是DLL所做的。我一直认为它做了类似的事情。库是预编译的。。。不一定,它们可能只包含标题。1。我没有提到TLB文件,它们略有不同,并且包含接口,因为它没有被广泛使用。2.只有标题的库包含文件而不是库。所以DLL就是这样做的。我一直认为它做了类似的事情。库是预编译的。。。不一定,它们可能只包含标题。1。我没有提到TLB文件,它们略有不同,并且包含接口,因为它没有被广泛使用。2.只有标题的库是包含文件而不是库。编译器无法执行您描述的操作。另一方面,链接器可以。@IInspectable,编译器和链接器之间的区别是什么?我假设编译器编译duh,但为什么需要链接器呢?链接器是预编译的吗?@Crysis编译器将人类可读的源代码转换为可执行的目标代码。链接器通过将目标代码链接在一起,解析函数调用和对象引用的符号,生成最终的可执行映像。作为副产品,链接器知道何时符号未被引用,并且可以从最终可执行映像中逐出。@IInspectable OK。谢谢那么,大多数编译器优化实际上是链接器吗?编译器不能做您描述的事情。另一方面,链接器可以。@IInspectable,编译器和链接器之间的区别是什么?我假设编译器编译duh,但为什么需要链接器呢?链接器是预编译的吗?@Crysis编译器将人类可读的源代码转换为可执行的目标代码。链接器通过将目标代码链接在一起,解析函数调用和对象引用的符号,生成最终的可执行映像。作为副产品,链接器知道何时符号未被引用,并且可以从最终可执行映像中逐出。@IInspectable OK。谢谢例如,大多数编译器优化实际上是链接器吗。例如,它声明了一些全局对象std::cout,其构造函数在调用main之前运行。例如,它声明了一些全局对象std::cout,其构造函数在调用main之前运行
#include <iostream>

int main()
{
   std::cout<<"Hello World.";
   return 0;
}