3

我有三个文件,比如 Ac 、 Bc 和 Cc,所有这些文件都是 #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

4

2 回答 2

0

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

于 2012-12-23T02:54:07.200 回答
0

这个问题几乎肯定与-combine. 这有点猜测,但在查看 的定义时recvmmsg

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

请注意,它需要 astruct 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仅对原型本地的定义,而第二个定义将使用真正的结构。这两个定义将不兼容,这将导致您收到错误消息。

于 2013-03-20T06:45:34.537 回答