Pregunta #incluyendo y da como resultado un conflicto de definición múltiple


Aquí está el programa de C mínima para reproducir:

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

int main( void )
{
}

Esto compilará con gcc -c -o timealsa.o timealsa.c, pero si incluyes el -std=c99 interruptor, obtienes un error de redefinición:

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

¿Cómo puedo resolver este conflicto mientras sigo usando -std=c99?


5
2017-09-19 19:28


origen


Respuestas:


Ya que su pregunta sugiere que está usando GLIBC time.h Hay una manera de evitar esto diciéndole que no defina timeval. Incluir asoundlib.h primero luego define _STRUCT_TIMEVAL. El definido en asoundlib.h Será el que se acostumbre.

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

int main( void )
{
}

5
2017-09-19 19:42



Con C99 y versiones posteriores, no puede tener definiciones duplicadas de la misma estructura. El problema es ese alsa/asoundlib.h incluye alsa/global.h que contiene este código:

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

Así que la solución de Michael Petch no funcionará, para cuando hayas incluido alsa/asoundlib.h ya es demasiado tarde La solución adecuada es definir. _POSIX_C_SOURCE (_POSIX_SOURCE es obsoleto). Hay más información sobre estas macros. aquí y aquí.

Por ejemplo usted podría intentar -D_POSIX_C_SOURCE=200809L. Sin embargo, si lo haces obtendrás errores como este:

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

Todo esto es un gran lío de código C antiguo y macro locura. La única forma en que lo pude hacer fue abandonar y usar -std=gnu11.


1
2018-06-03 17:36