2012-12-17 57 views
3

我有三個文件,說AC,BC和CC所有這些#包括COMMON.HGCC編譯時類型解析

在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 

上述錯誤可以通過提供「-combine -fwhole程序」的標誌與gcc如

再現

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

+1

檢查循環依賴關係;如果我沒有記錯,兩個包含對方的標題可能會導致這種情況。 – 2012-12-17 23:01:48

+3

顯示您的代碼。 – melpomene

+4

帶有兩個前導下劃線或帶有一個前導下劃線和大寫字母的標識符被保留供語言實現使用。 –

回答

0

錯誤是「recvmmsg'的衝突類型」,而不是僅僅重複的定義(如果相等,這將被容忍)。這意味着你的.c源代碼會收到兩個不同版本的recvmmsg:一個是你的直接tcpperf.h包含,另一個是通過sys/socket.h包含它。我相信你在其他地方有另一個版本的tcpperf.h,它包含不同的(也許是舊版本的)recvmmsg。

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的定義,而第二個定義將使用真實的結構。然後這兩個定義將不兼容,這會導致出現錯誤消息。