2015-09-19 24 views
5

Ecco il programma minimo C per riprodurre:#including <alsa/asoundlib.h> e <sys/time.h> risultati in molteplici conflitti definizione

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

int main(void) 
{ 
} 

Questo compilerà con gcc -c -o timealsa.o timealsa.c, ma se si include l'interruttore -std=c99, è un errore di ridefinizione:

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 { 
     ^

Come posso risolvere questo conflitto pur utilizzando -std=c99?

+0

È necessario utilizzare lo standard minimo di main che è ** int main (void) {return 0;} ** – Michi

+0

Sì, hai ragione (ma questa è un'altra riga!) – Lombard

+0

@Michi il 'return 0' è implicito se non presente in _C99_ (con cui questa domanda è contrassegnata con). Vedi: http://stackoverflow.com/questions/4138649/why-is-return-0-optional. Il vuoto è un problema anche se –

risposta

5

Poiché la tua domanda suggerisce che stai utilizzando il GLIBC time.h, c'è un modo per evitare ciò dicendo di non definire timeval. Includere asoundlib.h quindi definire _STRUCT_TIMEVAL. Quello definito in asoundlib.h sarà quello che viene utilizzato.

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

int main(void) 
{ 
} 
+0

Questo funziona - quindi cosa porta 'std = c99' alla tabella che ci rende quindi necessario disabilitare esplicitamente la definizione di timest di sys/time? – Lombard

+3

@Lombard it applica la conformità agli standard, quindi le ridefinizioni sono illegali. Prova 'std = c89', ti darà lo stesso risultato. –

+1

@Lombard: ho apportato una piccola modifica al codice per definire solo _STRUCT_TIMEVAL se non è già definito. Ci sono alcune opzioni di avviso come '-Wall' che possono prendere in considerazione la ridefinizione della definizione come problema. –

1

Con C99 e versioni successive non è possibile avere definizioni duplicate della stessa struttura. Il problema è che alsa/asoundlib.h include alsa/global.h che contiene questo codice:

/* 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 

Quindi la soluzione di Michael Petch non funziona - per il momento hai inserito alsa/asoundlib.h è già troppo tardi. La soluzione corretta è definire _POSIX_C_SOURCE (_POSIX_SOURCE obsoleto). Sono disponibili ulteriori informazioni su queste macro here e here.

Ad esempio, è possibile provare -D_POSIX_C_SOURCE=200809L. Tuttavia, se lo fai, riceverai errori come questo:

/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]) 
                  ^

Questo è tutto un gran casino del vecchio codice C e della follia della macro. L'unico modo per farlo funzionare era rinunciare e usare -std=gnu11.