#including <alsa/asoundlib.h> 和 <sys/time.h> 导致多重定义冲突

#including <alsa/asoundlib.h> and <sys/time.h> results in multiple definition conflict

这是要重现的最小 C 程序:

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

int main( void )
{
}

这将使用 gcc -c -o timealsa.o timealsa.c 进行编译,但如果包含 -std=c99 开关,则会出现重定义错误:

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

如何在仍然使用 -std=c99 的情况下解决此冲突?

由于您的问题表明您正在使用 GLIBC 的 time.h,因此有一种方法可以通过告诉它不要定义 timeval 来避免这种情况。首先包括 asoundlib.h,然后定义 _STRUCT_TIMEVALasoundlib.h 中定义的那个将被使用。

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

int main( void )
{
}

对于 C99 及更高版本,您不能对同一结构进行重复定义。问题是 alsa/asoundlib.h 包含 alsa/global.h 其中包含此代码:

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

所以 Michael Petch 的解决方案将不起作用 - 当您包含 alsa/asoundlib.h 时已经太晚了。正确的解决方案是定义 _POSIX_C_SOURCE_POSIX_SOURCE 已过时)。有关这些宏的更多信息 here and here.

例如,您可以尝试 -D_POSIX_C_SOURCE=200809L。但是,如果你这样做,你会得到这样的错误:

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

这完全是一堆旧 C 代码和疯狂的宏。我让它工作的唯一方法是放弃并使用 -std=gnu11.