【问题标题】:#including <alsa/asoundlib.h> and <sys/time.h> results in multiple definition conflict#include <alsa/asoundlib.h> 和 <sys/time.h> 导致多重定义冲突
【发布时间】:2015-12-16 19:15:06
【问题描述】:

这是要重现的最小 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 的同时解决此冲突?

【问题讨论】:

  • 您应该使用 main 的最低标准,即 int main(void){return 0;}
  • 是的,你是对的(但那是另一行!)
  • @Michi return 0 是隐含的,如果在 C99 中不存在(这个问题被标记)。请参阅:stackoverflow.com/questions/4138649/why-is-return-0-optional。空白是个问题
  • 由于问题集中在 c99 标准上,我将使其更符合标准。
  • 这是个坏主意,恕我直言,因为main() 不应该是“特殊的”。但实际上,这与这里完全无关。顺便说一句,int main(void) 也很好。

标签: gcc compiler-errors x86 c99 alsa


【解决方案1】:

由于您的问题表明您正在使用 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 )
{
}

【讨论】:

  • 这行得通 - 那么std=c99 带来了什么让我们需要显式禁用 sys/time 对 timeval 的定义?
  • @Lombard 它强制执行标准合规性,因此重新定义是非法的。试试std=c89,会得到同样的结果。
  • @Lombard :我对代码做了一些小改动,只定义 _STRUCT_TIMEVAL (如果尚未定义)。有一些警告选项,如 -Wall,可能会将重新定义定义为问题。
  • GCC 没有 time.h。你可能是说 glibc。根据目标系统,GCC 可以使用多种 libc 实现中的任何一种。
【解决方案2】:

对于 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 已过时)。有更多关于这些宏herehere 的信息。

例如,您可以尝试-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

【讨论】:

    猜你喜欢
    • 2011-08-17
    • 1970-01-01
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 2015-06-06
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多