关于头文件是否参与编译的讨论

一、文章来由

写项目的时候发现了这个问题,又是一个比较底层的问题,首先说明,这篇文章只是我根据查阅的资料和做的实验提出的一个讨论,并不一定就是正确答案。因为这个问题网上众说纷纭,我很欢迎大家参与这个讨论,一起搞懂这个问题~~~

二、问题的提出

问题就是。。。

2.1 问题1(主问题):

头文件是否真正参与编译?

先上一个网上的标准答案:

.h的内容被插入到.c中,作为.c的内容被编译。.h文件本身不直接参加编译。

据我理解,这句话就是说明了头文件不直接参与编译,是作为一个插入来理解。

也就是说:

是要编译的,只不过这些头文件是预编译的。每个源文件包涵的头文件都会被预编译包含到源文件中去。

这样就又牵出来三个子问题~~

2.2 问题2:

预编译是什么?

网上的答案大致理解为类似复制粘贴的操作,这样理解是有理由的,因为

(1)头文件不一定是 .h 文件,可以是任意类型

(2)头文件可以定义一些很奇怪的东西,见下面的代码

// testheadcompile.h
1, 2, 3, 4, 5//main.cpp
#include <iostream>
using namespace std;int main()
{int a[] = {#include "testheadcompile.h"};cout<<a[1]<<endl;return 0;
}

分析:
这段代码可以说是真的变态,因为头文件写在了函数体内,这么说的确就像是一个复制粘贴,关键是可以跑出结果,我在vs2012 release模式下,结果如下:

这里写图片描述

而且还被360误认为是木马。。。

于是我这样认为:如果需要什么东西(变量或者方法)的时候,就直接可以像利用 #define 一样用 #include 了?而且#include,有井号本身就是宏的写法~~

但是发现,把 include 像上面一样写在方法体内,定义变量可以,函数不行,否则会报“本地函数定义是非法的”的错,但如果 include 在开头,就可以正常使用函数。这又是一个预处理的典型代表,说明了在函数里面定义了函数~~~

其实甚至可以写出这种鬼畜的代码:

// testheadcompile.h
1, 2, 3, 4//main.cpp
#include <iostream>
using namespace std;int main()
{int a[] = {#include "testheadcompile.h",5};cout<<a[4]<<endl;return 0;
}

答案是5

2.3 问题3:

既然上面说是预编译,或者说是单纯的复制,那么那些没有实现的函数预编译?编译?链接的时候编译器怎么做的?那些实现了,在整个过程没有用到的函数呢???

这个问题,我是这样看的:

所有的编译都是单独的,没有实现的函数,就没有单独实现的编译,如果用到了,找不到实现体,就会报链接错误,也就是vs里面常见的“fatal error LNKXXX: N 个无法解析的外部命令”。。。

而对于头文件的作用仅仅是为了在编译的时候告诉编译器,这里如果用到一些其他文件的东西,我实现了,编译别报错!

所以这么说,实现了,但在整个过程没有用到的函数,是编译了的,但没有被链接进最后的可执行文件。(可能有不对的地方,欢迎指正)

2.4 问题4:

既然说没有参与编译,只是参与预编译,但是可以在头文件里面定义函数,又如何解释?

首先我来回答一下这个问题,个人感觉是参与编译的,但是是头文件被包含到源文件进行编译,也就是说编译器只会编译源文件,不被包含的头文件是没有存在的意义的,因为我故意把头文件写错,然后这样报错。。。

这里写图片描述

刚刚测试发现了一个现象,没有cpp文件,vs也可以编译,我怀疑在编译的时候,默认将main函数所在的文件作为编译文件,即使main函数写在头文件,也可以正常执行。

而在Linux下面,用编译器编译时需要指定编译的文件,所以有没有后缀名是无关紧要的,反正都是文本文件,读取方式就是确定的,所以Linux对于后缀名并不重要。

这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544387.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Log4j漏洞?一行代码都不改就能永久修复?

△Hollis, 一个对Coding有着独特追求的人△作者 l Hollis来源 l Hollis&#xff08;ID&#xff1a;hollischuang&#xff09;这篇文章我周一发过&#xff0c;但是因为一些"人在江湖、身不由己"的原因&#xff0c;原文删除了&#xff0c;但是很多人找我还是想看看内容…

服务器自动抢占GPU运行程序

其原理是通过nvidia-smi扫描每块显卡上的内存&#xff0c;然后查询已经使用的内存&#xff0c;若已经使用的显卡内存不大于一个阈值&#xff0c;则运行python脚本&#xff08;你也可以替换成别的命令&#xff09; #!/bin/bash var0 ocp_memory${2:-500} while [ $var -eq 0 ] …

java range类_Java即时类| range()方法与示例

java range类即时类range()方法 (Instant Class range() method) range() method is available in java.time package. range()方法在java.time包中可用。 range() method is used to get the valid range of values for the given TemporalField. range()方法用于获取给定Temp…

ubuntu安装eclipse

2019独角兽企业重金招聘Python工程师标准>>> 在Ubuntu 13.04下的安装eclipse 一、eclipse安装过程 首先确保在安装eclipse之前已经安装好Java虚拟机 1. eclipse官网下载压缩包 下载地址&#xff1a;http://www.eclipse.org/downloads/download.php?file/technology…

java的parse方法_Java即时类| parse()方法与示例

java的parse方法即时类parse()方法 (Instant Class parse() method) parse() method is available in java.time package. parse()方法在java.time包中可用。 parse() method is used to get an Instant that parses the given char sequence and char sequence follow some st…

github果然强大

github果然强大&#xff0c;在idea里写好&#xff0c;可以直接提交到github&#xff0c;在哪台电脑都可以看源码了&#xff0c;手机也可以看 https://github.com/gaojinhua 转载于:https://www.cnblogs.com/gaojinhua/p/4705992.html

Python用sorted实现argsort

\qquadsorted函数会返回一个可迭代对象经过排序后的迭代器&#xff0c;sorted对于number类型的可迭代对象会按照数值大小排序&#xff0c;对于字符串则按照ASCII码顺序排序&#xff0c;但如果要返回排序的index怎么呢&#xff1f; \qquadsorted有一个功能就是根据key参数比较大…

保姆级教程,终于搞懂脏读、幻读和不可重复读了!

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;我的文章合集&#xff1a;https://gitee.com/mydb/interview在 MySQL 中事务的隔离级别有以下 4 种&#xff1a;读未提交&am…

c++中cend end_vector :: cend()函数以及C ++ STL中的示例

c中cend endC vector :: cend()函数 (C vector::cend() function) vector::cend() is a library function of "vector" header, it can be used to get the last element of a vector. It returns a const iterator pointing to the past-the-end element of the ve…

alert提示框样式

http://runjs.cn/detail/pembjylb转载于:https://www.cnblogs.com/bky-234/p/4706103.html

保姆级教程,终于搞懂脏读、幻读和不可重复读了!(经典回顾)

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;我的文章合集&#xff1a;https://gitee.com/mydb/interview在 MySQL 中事务的隔离级别有以下 4 种&#xff1a;读未提交&am…

Python | 如何创建模块(模块示例)?

This is an example of creating module in python. Module files are special file that are used as library files and can be accessed in another file. 这是在python中创建模块的示例 。 模块文件是用作库文件的特殊文件&#xff0c;可以在另一个文件中访问。 In this e…

WPF入门教程系列十五——WPF中的数据绑定(一)

使用Windows Presentation Foundation (WPF) 可以很方便的设计出强大的用户界面&#xff0c;同时 WPF提供了数据绑定功能。WPF的数据绑定跟Winform与ASP.NET中的数据绑定功能类似&#xff0c;但也有所不同&#xff0c;在 WPF中以通过后台代码绑定、前台XAML中进行绑定&#xff…

实战,实现幂等的8种方案!

前言 大家好&#xff0c;我是程序员田螺。今天我们一起来聊聊幂等设计。什么是幂等为什么需要幂等接口超时&#xff0c;如何处理呢&#xff1f;如何设计幂等&#xff1f;实现幂等的8种方案HTTP的幂等1. 什么是幂等? 幂等是一个数学与计算机科学概念。在数学中&#xff0c;幂等…

灰度共生矩阵及其数字特征_数字系统及其表示

灰度共生矩阵及其数字特征Any number system has a set of symbols known as Digits with some rules performing arithmetic operations. A collection of these makes a number has two parts. They are integer portion and fraction portion. These portions are separated…

绝绝子,画框架图就用这个工具

前言看过我以往文章的小伙伴可能会发现&#xff0c;我的大部分文章都有很多配图。我的文章风格是图文相结合&#xff0c;更便于大家理解。最近有很多小伙伴发私信问我&#xff1a;文章中的图是用什么工具画的。他们觉得我画的图风格挺小清新的&#xff0c;能够让人眼前一亮。先…

Linux解析内核源代码——传输控制块诞生

原创文章是freas_1990&#xff0c;转载请注明出处&#xff1a;http://blog.csdn.net/freas_1990/article/details/23795587 在Linux 2.6一旦&#xff08;不包含2.6&#xff0c;对于更详细的调查是不是版本号&#xff09;&#xff0c;控制块的概念&#xff0c;各种协议的状态管理…

面试官:this和super有什么区别?this能调用到父类吗?

作者&#xff1a;磊哥来源 | Java面试真题解析&#xff08;ID&#xff1a;aimianshi666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;本文已收录《Java常见面试题》&#xff1a;https://gitee.com/mydb/interviewthis 和 super 都是 Java 中常…

scala中map添加值_如何在Scala Map中反转键和值

scala中map添加值A Map is a data structure that stores data as key: value pair. 映射是一种将数据存储为键&#xff1a;值对的数据结构。 Syntax: 句法&#xff1a; Map(key->value, key->value)反转地图中的键和值 (Reversing Keys and values in Map) Here, we w…

在 Exchange 服务器上的操作系统中的防病毒软件

本主题介绍文件级防病毒程序对运行 Microsoft Exchange Server 2013 的计算机的影响。如果按照本主题中所述的建议操作&#xff0c;可以帮助提高 Exchange 组织的安全性并改善运行状况。文件级扫描程序经常使用。但是&#xff0c;如果配置不正确&#xff0c;可能会导致 Exchang…