关于在头文件中实现函数的情况

原创 2013年12月04日 01:41:43
下面举个例子,这个例子只有3个文件

/* fun.h */
#ifndef FUN_H
#define FUN_H
void base(){};
void fun();
#endif 

/* fun.c */
#include "fun.h"
void fun()
{
    base();
}

/* main.c */
#include "fun.h"
int main()
{
    fun();
    return 0;
}

$gcc -c fun.c

$gcc -c main.c

$gcc -o main main.c fun.c

则会在链接是时候报重复定义base()的错误!

fun.o: In function `base':
fun.c:(.text+0x0): multiple definition of `base'
main.o:main.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit statu

注:开始时在对这行忽然很陌生,main.c中的fun(); 突然搞不清这行代码做了什么事了!fun的函数体是调用base()方法,虽然fun是在fun.c中实现的,但在main.c文件中用,

应该是调用main.c中的base()还是fun.c中的base()呢?其实,链接器自己都搞不清清楚了,所以报错了!


这里我突然想到一个问题:如在main中调用strlen(),但是编译的时侯,仅仅编译test.c,$gcc test.c即可!不需要编译strlen所在的.c文件吗?这个该怎么解释呢?

是不是这样的,这些标准函数已经编译成了动态链接库,程序编译后,直接链接就可以!但是,是通过什么样的方法找到对应的动态链接库文件呢?

对比自己写的函数API怎么才能像系统的strlen()一样呢?直接编译调用函数的那个文件?(待补充。欢迎赐教....)


对于上面的程序,如果这样编译

$gcc -c fun.c

$gcc -o main main.c

则报没有定义fun的错误;

/tmp/ccRYqwWl.o: In function `main':
main.c:(.text+0xc): undefined reference to `fun'        //未定义引用到‘fun’,因为fun.h中的fun();仅是声明!
collect2: error: ld returned 1 exit status,


---------------------------------------------------------------------------------------

为什么重定义呢?因为#include是预处理部分,在编译之前由预处理程序在这个部分复制头文件的内容过来。所以在编译时候,main.o和fun.o文件都有base()函数的定义。那么链接程序就不知道链接那个定义好了(二义性啊)

如何解决呢,为了实现“声明和实现分开”这个目标最好就是把这个base函数的函数体移到源文件里面。如果由于某种原因真的要放在头文件中...也可以。

static声明就可以了,静态函数的作用域是文件,而不是全局。比如,上面的例子将头文件里面的void base(){}改成static void base(){},那就OK。








版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

函数实现不放在头文件的原因,及何时可以放头文件的情况

1 、引子        在平常的 C/C++ 开发中,几乎所有的人都已经习惯了把类和函数分离放置,一个 .h 的头文件里放声明,对应的 .c 或者 .cpp 中放实现...

头文件中写类的实现出现函数重复定义的问题

先来做一个实验,你在一个头文件中定义一个类,然后把内中的一个函数的实现写在这个头文件当中。 //A_test.h #ifndefine _A_TEST_ #define _A_TEST_ ...

函数实现不放在头文件的原因,及何时可以放头文件的情况

原文 : http://hi.baidu.com/pope123/item/f2eb0b2fb6a2110e73863e71 1 、引子 这篇文章的题目念起来比较怪,...

函数实现不放在头文件的原因,及何时可以放头文件的情况

1 、引子        在平常的 C/C++ 开发中,几乎所有的人都已经习惯了把类和函数分离放置,一个 .h 的头文件里放声明,对应的 .c 或者 .cpp 中放实现。从开始接触,到熟练使用,几乎...

用头文件stdarg中的宏来实现函数的变参

strarg.h可以实现变参。 在这个头文件中有四个宏用来处理变参。 va_list 是一个指针,用来指向参数第一个参数的首地址 va_start是用来初始化这个指针的,参数为va_list和有...

头文件里面实现一个函数,在两个cpp中包含,则重复定义,如果加上inline则不会报错

为什么类的定义应当写在头文件中,从而被多个源文件包含?比如myclass.h定义了一个类myclass(只定义类,不定义成员函数), file1.cpp里#include "myclass.h",编译...

c++ 头文件<cwchar>中常见函数的实现!!!

c++ 头文件中常见函数的实现!!!这里有wcsncmp,wcsncat,wmemmove,wmemcpy函数的实现!!!

手动实现的C语言string.h 头文件的字符串函数

研究C语言,首先要明白其库函数…001#include 002char* strcpy(char* dest,constchar* src);  //字符串拷贝 003char* strcat(cha...

c++ 头文件<cstring>(或者string.h)中的常见函数的实现!

c++ 头文件(或者string.h)中的常见函数的实现!

C++学习笔记01之类的基本实现过程(头文件的防卫式定义, 具体类的定义和实现, 函数的传递类型和返回类型)

一、C++简介        首先,C++是一门从C语言(过程式编程语言)演化过来的面向对象的编程语言(OOP)。相对于其它的面向对象的编程语言,如Java、C#,C++具有性能优化和底层开发的特点。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)