函数的实现是在工程里自己写的,c函数库也自带该函数,编译器只执行了其中一个而不报重复定义的错,为什么?该怎么解决
函数的实现是在工程里自己写的,c函数库也自带该函数,编译器只执行了其中一个而不报重复定义的错,为什么?
最近在学《UNIX网络编程》,但是下面我要问的问题却是一般的程序设计都会遇到的情况:
具体举些例子:
例如,编写一个socket的应用时,会有下面的代码:
这里的bzero有两个实现,一个是书中源码在 unp.h (作者自己写的头文件)中的宏定义:
另一个就是<strings.h>中已做包含:
我的疑问是:编译器在编译时,会选择哪个呢??
再举一个例子:
程序中还用到信号处理函数
此函数<signal.h>中也是包含的:
此外,我也自己写了个signal函数的实现放在code::blocks的工程里,
这样signal函数也是两个,编译器如何知道要调用哪个函数,是默认调用工程里自己写的?(我跟踪了下发现的确只调用了自己写的,不再执行signal.h中的那个)。
想请教各位大侠,这该如何解释?就是编译器选择执行哪个函数?为什么不会报重复定义的错误?
------解决方案--------------------
#ifndef HAVE_BZERO
#ifdef __USE_BSD
不是都有条件编译么?如果你#define了这些宏那么就可能引起冲突了。
------解决方案--------------------
1. 宏替换的过程是比查找函数更早的, 如果你确认没有定义 HAVE_BZERO 宏, 而且使用 bzero 的 cpp 文件中包含了 unp.h, 那么它会被替换成 memset.
2. 同是函数的情况下, 连接的顺序是按参数给出来的顺序. 当然工程中的代码应该是比库优先的. 具体查看 IDE 的命令行或生成的 makefile 文件.
------解决方案--------------------
最近在学《UNIX网络编程》,但是下面我要问的问题却是一般的程序设计都会遇到的情况:
具体举些例子:
例如,编写一个socket的应用时,会有下面的代码:
- C/C++ code
bzero(&servaddr, sizeof(servaddr));
这里的bzero有两个实现,一个是书中源码在 unp.h (作者自己写的头文件)中的宏定义:
- C/C++ code
/* Define bzero() as a macro if it's not in standard C library. */ #ifndef HAVE_BZERO #define bzero(ptr,n) memset(ptr, 0, n) #endif
另一个就是<strings.h>中已做包含:
- C/C++ code
/* Set N bytes of S to 0. */ extern void bzero (void *__s, size_t __n) __THROW;
我的疑问是:编译器在编译时,会选择哪个呢??
再举一个例子:
程序中还用到信号处理函数
- C/C++ code
signal(SIGCHLD,sig_chld);
此函数<signal.h>中也是包含的:
- C/C++ code
/* Set the handler for the signal SIG to HANDLER, returning the old handler, or SIG_ERR on error. By default `signal' has the BSD semantic. */ __BEGIN_NAMESPACE_STD #ifdef __USE_BSD extern __sighandler_t signal (int __sig, __sighandler_t __handler) __THROW; #else
此外,我也自己写了个signal函数的实现放在code::blocks的工程里,
- C/C++ code
Sigfunc * signal(int signo, Sigfunc *func) { ... /* end signal */
这样signal函数也是两个,编译器如何知道要调用哪个函数,是默认调用工程里自己写的?(我跟踪了下发现的确只调用了自己写的,不再执行signal.h中的那个)。
想请教各位大侠,这该如何解释?就是编译器选择执行哪个函数?为什么不会报重复定义的错误?
------解决方案--------------------
#ifndef HAVE_BZERO
#ifdef __USE_BSD
不是都有条件编译么?如果你#define了这些宏那么就可能引起冲突了。
------解决方案--------------------
1. 宏替换的过程是比查找函数更早的, 如果你确认没有定义 HAVE_BZERO 宏, 而且使用 bzero 的 cpp 文件中包含了 unp.h, 那么它会被替换成 memset.
2. 同是函数的情况下, 连接的顺序是按参数给出来的顺序. 当然工程中的代码应该是比库优先的. 具体查看 IDE 的命令行或生成的 makefile 文件.
------解决方案--------------------