注册 登录
编程论坛 C语言论坛

为什么linux双链表的函数实现写在头文件里?

KAKA55 发布于 2018-06-21 10:12, 3339 次点击
如题,为什么linux双链表的函数实现写在头文件里?如果我有两个.c文件都用这个头文件,这样会不会带来一个双链表函数被编译多次从而在代码中生成多个副本的问题?
18 回复
#2
lin51616782018-06-21 10:29
全部都加了 static
没关系的
#3
KAKA552018-06-21 10:47
回复 2楼 lin5161678
是加了static,但如果我两个c文件里都包含了这个头文件,编译时岂不是被编译两次,生成两段一样的代码》
#4
lin51616782018-06-21 11:15
回复 3楼 KAKA55
有没有inline
有的话就不用管
编译器有优化
#5
KAKA552018-06-21 14:50
回复 4楼 lin5161678
有inline,请问如果没有inline是不是就会生成多段重复的代码?
#6
花脸2018-06-21 15:40
你可以把实现单独写出来,夹头文件编译的时候加上#program once
#7
八画小子2018-06-21 20:30
static表示编译生成的目标文件符号表中不会产生相应的信息,也就是说用了static的函数以及变量只能在自己所在的.c(或等同的)源代码文件中才能被引用。(专业一点就是说,只能在自己所在的编译单元中被看到。)所以多个地方引用不会出现链接错误。
#8
八画小子2018-06-21 20:31
以下是引用lin5161678在2018-6-21 11:15:53的发言:

有没有inline
有的话就不用管  
编译器有优化
楼主问的问题和有没有inline没关系。
#9
八画小子2018-06-21 20:32
以下是引用花脸在2018-6-21 15:40:19的发言:

你可以把实现单独写出来,夹头文件编译的时候加上#program once
用#program once的话,就是画蛇添足了。本质是没有理解static的用法。
#10
花脸2018-06-21 20:39
回复 9楼 八画小子
static的含义:
static修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。
static修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是extern外部声明也不可以。
我的意思是加上#program once 就不用加static
#11
八画小子2018-06-21 20:44
以下是引用花脸在2018-6-21 20:39:43的发言:

static的含义:
static修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。
static修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是extern外部声明也不可以。  
我的意思是加上#program once 就不用加static
自己弄懂就好,但别误导别人。“我的意思是加上#program once 就不用加static”几乎没人用这种用法。static是语法层面的东西,#program是编译器层面的东西。
#12
花脸2018-06-21 20:50
回复 11楼 八画小子
恩好的 谢谢。
#13
lin51616782018-06-22 00:32
以下是引用花脸在2018-6-21 20:39:43的发言:

static的含义:
static修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。
static修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是extern外部声明也不可以。
我的意思是加上#program once 就不用加static

错的
首先 #program once 实现定义
换一个编译器可能就没有这个预编译指令
static 和 #program once 功能上没什么关联
#program once 和 #ifndef常见用法 一个作用
static这里是限制文件作用域的标识符没有外部链接的效果
不管是#program once 还是 #ifndef 都无法做到这一点
加了 #program once 不加 static 一样会报错
#14
lin51616782018-06-22 09:51
以下是引用八画小子在2018-6-21 20:31:12的发言:

楼主问的问题和有没有inline没关系。

是加了static,但如果我两个c文件里都包含了这个头文件,编译时岂不是被编译两次,生成两段一样的代码》

题主问 是不是会编译两次生成一样的代码
我回答 有加inline 不用考虑这个问题
有问题吗?
#15
九转星河2018-06-22 15:31
其实,在没有加static的情况下也可以直接引用,头文件就是简单的复制粘贴,弄清楚函数的作用域就可以了,当然头文件里面的变量不加static就是公共的了,就相当于一个全局变量~

其实楼主所说的多个.c,如果加了static引用同一个头文件的确会生成重复的代码,但加了static变量间(如果有变量的话……其实通常没事不会把一个变量写进头文件里面的)不会发生冲突,更何况.h里面通常只有函数的定义而没有实体函数,所以多个.c引用同一个头文件就是说多个.c都能够使用.h里面声明的那些函数而已~

但看了的确会有简化编译处理而把函数实现主体写进.h里面的情况,"list.h"就是一个例子~但加了就像楼上有说加了inline关键字会直接把实现主体代码会在调用函数的时候直接展开,因此不用考虑是否生成重复代码这是有一定的道理的(其实用inline多次调用同一个函数已经有重复的代码了)

如果不打算生成重复的代码,就用接口分离吧(简单说就是.h是函数接口,函数实现主体在.c里面),那样函数实现主体只会被编译一次,但对于"list.h"的系统提供头文件来说,把它实现接口分离不怎么现实而且没啥实用性,所以如果要让多个.c要同时引用"list.h"的话,直接用就可以了,没问题的

其实,出现因为多文件编译发生错误的情况通常是同一个头文件里面的定义在其作用域范围内重复定义了一次,这种情况可以用#ifndef或者#pragma once来解决,而和多个.c文件引用而发生的问题无关,至于是否生成重复的编码对于"list.h"而言是一个不用考虑的问题~

[此贴子已经被作者于2018-6-22 15:55编辑过]

#16
八画小子2018-06-23 08:21
以下是引用lin5161678在2018-6-22 09:51:39的发言:

 
 
题主问 是不是会编译两次生成一样的代码  
我回答 有加inline 不用考虑这个问题
有问题吗?
inline这东西,个人感觉不好控制最终的编译结果。是否真的要inline,是要看具体实现的。或许你想要inline的时候,编译器却没有inline。
#17
九转星河2018-06-23 09:59
以下是引用八画小子在2018-6-23 08:21:08的发言:

inline这东西,个人感觉不好控制最终的编译结果。是否真的要inline,是要看具体实现的。或许你想要inline的时候,编译器却没有inline。



曾经试过用inline写递归,哇,竟然可以通过编译,后来我才知道这是一个问题~

但既然楼主说是用系统头文件,那应该是经过严格测试才发布的,所以inline应该没有问题,不然那不成笑话么~
#18
lin51616782018-06-23 16:04
回复 16楼 八画小子
"linux双链表的函数实现写在头文件"
你觉得写这段代码的人 没搞懂会不会 inline ?
#19
八画小子2018-06-24 17:19
以下是引用lin5161678在2018-6-23 16:04:27的发言:

"linux双链表的函数实现写在头文件"
你觉得写这段代码的人 没搞懂会不会 inline ?

写linux内核源代码的人会,但其他个别人就不好说了。
1