gcc编译时间类型解析

时间:2012-12-17 22:58:15

标签: c linux gcc

我有三个文件,比如A.c,B.c和C.c,所有这些文件#include common.h

在common.h中,我包含“sys / socket.h”,我通过宏保护common.h:

#ifndef __COMMON_H
#define __COMMON_H
// body of file goes here
#endif

当我编译代码时,我会收到几个错误,如下面的

In file included from /usr/include/sys/socket.h:40,
             from tcpperf.h:4,
             from wrapunix.c:1:
/usr/include/bits/socket.h:425: error: conflicting types for 'recvmmsg'
/usr/include/bits/socket.h:425: note: previous declaration of 'recvmmsg' was here
In file included from /usr/include/sys/socket.h:40,
             from tcpperf.h:4,
             from wrapsock.c:1:

正如你可以看到wrapunix.c和wrapsock.c,它们都包含tcpperf.h,但是tcpperf.h是用宏来保护的,但是gcc抱怨recvmsg被多次声明了。我该如何解决这个问题?

更新: 这是tcpperf.h的标题,导致问题

#ifndef _TCPPERF_H
#define _TCPPERF_H
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include <regex.h>
#include <errno.h>
#include <sched.h>
#include <pthread.h>
#include <argp.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <linux/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/prctl.h>
#include <unistd.h>
#include <sys/wait.h>
#endif

通过向gcc提供“-combine -fwhole-program”标志可以重现上述错误,例如

gcc -std = gnu99 -Wall -combine -fwhole-program -I。 error.c wrapunix.c wrapsock.c file1.c file2.c -o file2 -lrt

2 个答案:

答案 0 :(得分:0)

错误是“recvmmsg'的冲突类型”,而不仅仅是重复定义(如果相等则可以容忍)。这意味着你的.c源代码接收两个不同版本的recvmmsg:一个由你的直接tcpperf.h包含,另一个通过sys / socket.h包含它。我相信你在包含路径的其他地方有另一个版本的tcpperf.h与不同的(可能是旧版本)recvmmsg。

答案 1 :(得分:0)

问题几乎肯定与-combine有关。这是一个猜测,但在查看recvmmsg

的定义时
extern int recvmmsg (int __fd, struct mmsghdr *__vmessages,
                     unsigned int __vlen, int __flags,
                     __const struct timespec *__tmo);

请注意,它需要struct mmsghdr作为参数。但是,虽然此原型是无条件的,但struct mmsghdr仅在设置__USE_GNU时定义:

#ifdef __USE_GNU
/* For `recvmmsg'.  */
struct mmsghdr
  {
    struct msghdr msg_hdr;      /* Actual message header.  */
    unsigned int msg_len;       /* Number of received bytes for the entry.  */
  };
#endif

-combine基本上相当于将所有文件连接在一起然后编译它们。在wrapunix.cwrapsock.c的文本之间是否有可能定义GNU_SOURCE?如果发生了这种情况,那么recvmmsg的第一个定义将使用struct mmsghdr的定义,该定义仅仅是原型的本地定义,而第二个定义将使用真实的结构。这两个定义将是不兼容的,这将导致您得到的错误消息。