头文件被多个源文件包含的问题

xztquan 2008-03-07 11:12:58
一个头文件被多个源文件包含。所有文件在一个工程里。

请问:
1、每个源文件均调用了头文件中的函数,系统链接时怎么解决重复定义问题?
2、没有调用头文件的函数,是不是系统就不处理了?
3、头文件中内联函数是怎么处理的?
4、如果头文件中的内联函数没被内联,是不是就和普通的函数一样处理了?(新规、旧规区别?)


以上。

这些问题比较头疼,望各大虾解答一二。

WAIT.................
...全文
1097 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
xztquan 2008-03-10
  • 打赏
  • 举报
回复
谢谢大家了!

本人愚笨,问题说的不明白。

现在已经知道答案了。

普通函数,在头文件中实现,如果被多个文件包好,链接时是一定出错。

而头文件中的inline函数,如果编译器决定不对其内联的话,变成了普通函数,但是处理自然与普通函数不一样,在链接的时候是不会报错的。问题就出来了,编译器旧的处理规则已经知道,想知道一下新规则下编译器是怎么处理的
IT_lau 2008-03-08
  • 打赏
  • 举报
回复
#ifndef
#define
#endif
星羽 2008-03-08
  • 打赏
  • 举报
回复

一个头文件被多个源文件包含。所有文件在一个工程里。

请问:
1、每个源文件均调用了头文件中的函数,系统链接时怎么解决重复定义问题?

.h文件一般只声明函数,而函数体,也就是函数的实现部分要放到相应的cpp里
只有inline和class 内定义的函数可以放到.h里,再加上使用#ifndef #define宏
就可以确保一个cpp只导入这个.h的声明一次

如果你把普通函数的实现放在.h里,那么当多个cpp同时include这个.h的时候,就
会出现重定义错误,这个编译器会告诉你


2、没有调用头文件的函数,是不是系统就不处理了?

这个你不太需要去关系,各给编译器可能有不同的实现
你说的不处理是什么意思?一般来说所有的函数都会生
成对于的2进制指令,用不用时另外的事,但如果对于
dll,一个没使用函数是否载入那就跟系统相关了,这个不
深究


3、头文件中内联函数是怎么处理的?

#include 就相当于把.h文件的内容在你的#include地方展开
对于inline编译器在可能的情况下会把代码复制到你使用它的地方

4、如果头文件中的内联函数没被内联,是不是就和普通的函数一样处理了?(新规、旧规区别?)
应该是按普通函数处理
cnzdgs 2008-03-08
  • 打赏
  • 举报
回复
LZ是把函数体写在头文件里面吗?
如果把函数体写在头文件里面,如果是内联函数,其代码是在调用该函数的模块中生成的,如果内联则生成在执行调用的代码处,如果没有内联则在模块中生成一个函数;如果是类中定义的方法,会被看作是类定义的一部分,只生成一份代码;如果是类的方法的外部实现或者是全局函数,则连接会报错。
如果只是把函数声明写在头文件里,实际上并不生成代码,而每个源文件编译时是相互独立的,在连接时才会寻找函数体,所以没有重复定义的问题。
arong1234 2008-03-08
  • 打赏
  • 举报
回复
1、每个源文件均调用了头文件中的函数,系统链接时怎么解决重复定义问题?
函数定义不能放在头文件中,头文件只能放函数原型,如果你放了函数体,此题无解

2、没有调用头文件的函数,是不是系统就不处理了?
当然
3、头文件中内联函数是怎么处理的?
内联函数不一定会特别处理,inline不是强制性规定。如果处理了,编译器会把对应的函数代码直接插入被调用处

4、如果头文件中的内联函数没被内联,是不是就和普通的函数一样处理了?(新规、旧规区别?)
当然


gytxzyf 2008-03-08
  • 打赏
  • 举报
回复
在文件头里加个#pragma once试试
openwn_2 2008-03-08
  • 打赏
  • 举报
回复
#ifndef xxx
#define xxx
...
#endif
vcf_reader 2008-03-07
  • 打赏
  • 举报
回复
问题太简单了。
qiuqiu173 2008-03-07
  • 打赏
  • 举报
回复
#ifndef
#define

#endif
abupie 2008-03-07
  • 打赏
  • 举报
回复
第2个问题 不直接给楼主答案了.
如果搂主是使用linux/gcc, 那可以自己写个小程序, 然后用nm命令查看符号表.
abupie 2008-03-07
  • 打赏
  • 举报
回复
1. 头文件中是声明, 没有定义. 定义才是真正的为数据分配空间,声明只是提供原形.
用#ifndef 避免了重复声明, 编译的时候会连接同一份数据.

abupie 2008-03-07
  • 打赏
  • 举报
回复
3. 引入内联函数的目的是为了解决程序中函数调用的效率问题。
在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来进行替换。显然,这种做法不会产生转去转回的问题,但是由于在编译时将函数休中的代码被替代到程序中,因此会增加目标程序代码量,进而增加空间开销,而在时间代销上不象函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。调用其函数时,该函数在编译时被替代,而不是像一般函数那样是在运行时被调用。
内联函数具有一般函数的特性,它与一般函数所不同之处公在于函数调用的处理。一般函数进行调用时,要将程序执行权转到被调用函数中,然后再返回到调用它的函数中;而内联函数在调用时,是将调用表达式用内联函数体来替换。

4. 如果头文件中的内联函数没被内联? 怎么理解?
xztquan 2008-03-07
  • 打赏
  • 举报
回复
问题1继续。


sinosinux 看来没理解我的意思。
你说的是防止头文件被重复包含。

我说的是每个源文件之间是不存在包含关系的。

sinosinux 2008-03-07
  • 打赏
  • 举报
回复
没被使用的内联函数编译器的处理好想不一样, 有的在每个目标文件中都产生个static链接的函数, 有的是在某个特定的目标文件中产生一个函数提
xztquan 2008-03-07
  • 打赏
  • 举报
回复
看了一下,没内联的函数用“被外联的内联函数”原则处理。

就是通过static的拷贝来解决的。

旧规明白,但是新规是对所有编译单元就产生一个static的拷贝,这各过程就不明白了。

难道普通函数就是和新规一样解决“被外联的内联函数”的方法处理的?
Supper_Jerry 2008-03-07
  • 打赏
  • 举报
回复
楼上正解,在头文件中加上
#ifndef
#define
#endif
sinosinux 2008-03-07
  • 打赏
  • 举报
回复
1. 使用
#ifndef xxx 
#define xxx
your decleration
#endif

2. 处理, 头文件的处理是在编译前进行的, 头文件里面是声明, 不会增加目标文件的大小
3. 内敛函数在被调用点展开
4. 什么叫作内联函数没被内联?
taodm 2008-03-07
  • 打赏
  • 举报
回复
楼主啊,问题1你自己编译试一下不就知道了.
后面的问题,找<Exceptional C++><More Exceptional C++><<Exceptional C++ Style>看关于inline的item
p0303230 2008-03-07
  • 打赏
  • 举报
回复
1 #ifndef
#define

#endif
p0303230 2008-03-07
  • 打赏
  • 举报
回复
mark
加载更多回复(2)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧