2015-09-19 43 views
5

Oto minimalny program C do reprodukcji:#including <alsa/asoundlib.h> i <sys/time.h> skutkuje wielokrotnym konfliktu definicji

#include <alsa/asoundlib.h> 
#include <sys/time.h> 

int main(void) 
{ 
} 

ta zostanie skompilowany z gcc -c -o timealsa.o timealsa.c, ale jeśli to przełącznik -std=c99, ty pojawia się błąd redefinicji:

In file included from /usr/include/sys/time.h:28:0, 
       from timealsa.c:3: 
/usr/include/bits/time.h:30:8: error: redefinition of ‘struct timeval’ 
struct timeval 
     ^
In file included from /usr/include/alsa/asoundlib.h:49:0, 
       from timealsa.c:2: 
/usr/include/alsa/global.h:138:8: note: originally defined here 
struct timeval { 
     ^

Jak mogę rozwiązać ten konflikt, jednocześnie korzystając -std=c99?

+0

Powinieneś użyć minimalnego standardu main, który jest ** int main (void) {return 0;} ** – Michi

+0

Tak, masz rację (ale to jeszcze jedna linia!) – Lombard

+0

@Michi 'return 0' jest niejawne, jeśli nie występuje w _C99_ (Jakie to oznaczenie to pytanie). Zobacz: http://stackoverflow.com/questions/4138649/why-is-return-0-optional. Nieważne jest problem, ale –

Odpowiedz

5

Ponieważ twoje pytanie sugeruje, że używasz GLIBC's time.h istnieje sposób, aby tego uniknąć, mówiąc mu, aby nie definiować timeval. Najpierw dodaj asoundlib.h, a następnie zdefiniuj _STRUCT_TIMEVAL. Ta zdefiniowana w asoundlib.h będzie tą, która zostanie użyta.

#include <alsa/asoundlib.h> 
#ifndef _STRUCT_TIMEVAL 
# define _STRUCT_TIMEVAL 
#endif 
#include <sys/time.h> 

int main(void) 
{ 
} 
+0

To działa - więc co wywołuje tabela 'std = c99', która powoduje, że musimy wyraźnie wyłączyć definicję time-time sys/time? – Lombard

+3

@Lombard to wymusza zgodność ze standardami, więc redefinicja jest nielegalna. Wypróbuj 'std = c89', da taki sam wynik. –

+1

@Lombard: Wprowadziłem niewielką zmianę do kodu, aby zdefiniować _STRUCT_TIMEVAL, jeśli nie jest jeszcze zdefiniowany. Istnieją pewne opcje ostrzegawcze, takie jak '-Wall', które mogą odebrać redefinicję definicji jako problemu. –

1

Przy C99 i późniejszych nie można mieć duplikatów definicji tej samej struktury. Problemem jest to, że alsa/asoundlib.h obejmuje alsa/global.h która zawiera ten kod:

/* for timeval and timespec */ 
#include <time.h> 

... 

#ifdef __GLIBC__ 
#if !defined(_POSIX_C_SOURCE) && !defined(_POSIX_SOURCE) 
struct timeval { 
     time_t   tv_sec;   /* seconds */ 
     long   tv_usec;  /* microseconds */ 
}; 

struct timespec { 
     time_t   tv_sec;   /* seconds */ 
     long   tv_nsec;  /* nanoseconds */ 
}; 
#endif 
#endif 

Więc rozwiązanie Michaela Petch nie będzie działać - do czasu dołączyliśmy alsa/asoundlib.h jest już za późno. Właściwym rozwiązaniem jest zdefiniowanie przestarzałego kodu: _POSIX_C_SOURCE (_POSIX_SOURCE). Więcej informacji na temat tych makr można uzyskać pod here i here.

Na przykład możesz spróbować -D_POSIX_C_SOURCE=200809L. Jeśli jednak to zrobisz, dostaniesz takie błędy:

/usr/include/arm-linux-gnueabihf/sys/time.h:110:20: error: field ‘it_interval’ has incomplete type 
    struct timeval it_interval; 
        ^
/usr/include/arm-linux-gnueabihf/sys/time.h:112:20: error: field ‘it_value’ has incomplete type 
    struct timeval it_value; 
        ^
/usr/include/arm-linux-gnueabihf/sys/time.h:138:61: error: array type has incomplete element type 
extern int utimes (const char *__file, const struct timeval __tvp[2]) 
                  ^

To wszystko jest wielkim bałaganem starego kodu C i makro-szaleństwa. Jedynym sposobem, w jaki udało mi się go uruchomić, było zrezygnowanie i użycie -std=gnu11.