2015-09-19 20 views
5

結果が再現する最小限のCプログラムです: #including <ALSA/asoundlib.h>ここで、複数の定義が競合

#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を使用しながら、どのように私はこの競合を解決することができますか?

+0

** main main(void){return 0;} ** – Michi

+0

はい、あなたは正しいですが(それはもう一つの行です) – Lombard

+0

@Michi the return 0' _C99_に存在しない場合は暗黙的です(この質問にタグが付いている場合)。参照:http://stackoverflow.com/questions/4138649/why-is-return-0-optional。しかし、空白は問題です。 –

答えて

5

あなたの質問はGLIBCのtime.hを使用していることを示唆しているので、これを避ける方法はtimevalを定義しないように伝えることです。 asoundlib.hを最初に含め、_STRUCT_TIMEVALと定義します。 asoundlib.hで定義されたものが使用されます。

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

int main(void) 
{ 
} 
+0

これはうまくいくので、 'std = c99'がテーブルに持ってきてsys/timeのtimevalの定義を明示的に無効にする必要があるのは何ですか? – Lombard

+3

@ Lombardは標準準拠を強制するので、再定義は違法です。 'std = c89'を試してみてください。同じ結果が得られます。 –

+1

@ Lombard:まだ定義されていない場合は、_STRUCT_TIMEVALのみを定義するようにコードを少し変更しました。 '-Wall'のように、定義の再定義を問題として取り上げるかもしれない警告オプションがあります。 –

1

C99以降では、同じ構造体の定義を重複させることはできません。時間によって、あなたはそれが既に手遅れであるalsa/asoundlib.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 

だからマイケル・ペッチのソリューションが動作しません。問題は alsa/asoundlib.hは、このコードが含まれている alsa/global.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を使うことでした。

関連する問題