我不明白为什么编译器给我错误的代码

我有以下C代码,这对我来说看起来非常正确。 但是,clang编译器(实际上gcc或任何其他C编译器)则认为不然。

typedef struct { struct timeval td_start; struct timeval td_end; } Timer; void startTimer( struct Timer* ptimer ) { gettimeofday( &(ptimer->td_start), NULL ); } void stopTimer( struct Timer* ptimer ) { gettimeofday( &(ptimer->td_end), NULL ); } 

编译器给出以下waring&error消息。 任何想法这里有什么不对?

 ./timing.h:14:25: warning: declaration of 'struct Timer' will not be visible outside of this function [-Wvisibility] void startTimer( struct Timer* ptimer ) ^ ./timing.h:16:27: error: incomplete definition of type 'struct Timer' gettimeofday( &(ptimer->td_start), NULL ); ~~~~~~^ ./timing.h:14:25: note: forward declaration of 'struct Timer' void startTimer( struct Timer* ptimer ) ^ ./timing.h:19:24: warning: declaration of 'struct Timer' will not be visible outside of this function [-Wvisibility] void stopTimer( struct Timer* ptimer ) ^ ./timing.h:21:27: error: incomplete definition of type 'struct Timer' gettimeofday( &(ptimer->td_end), NULL ); ~~~~~~^ ./timing.h:19:24: note: forward declaration of 'struct Timer' void stopTimer( struct Timer* ptimer ) 

删除struct关键字(因为您已经typedef了结构体,所以不需要):

 void startTimer( Timer* ptimer ) { ... void stopTimer( Timer* ptimer ) { ... 

或者,删除typedef

 struct Timer { struct timeval td_start; struct timeval td_end; }; void startTimer( struct Timer* ptimer ) { ... void stopTimer( struct Timer* ptimer ) { ... 

有关更多信息,请参阅为什么要在C中经常键入一个结构?

或者你

 struct Timer { struct timeval td_start; struct timeval td_end; }; void startTimer( struct Timer* ptimer ) { gettimeofday( &(ptimer->td_start), NULL ); } 

或者你

 typedef struct { struct timeval td_start; struct timeval td_end; } Timer; void startTimer( Timer* ptimer ) { gettimeofday( &(ptimer->td_start), NULL ); } 

但不要混淆。

您创建了一个名为Timer的类型,只需在函数参数之前删除struct这个字就可以了,例如:

 void startTimer( Timer* ptimer ) { gettimeofday( &(ptimer->td_start), NULL ); } 

错误的原因是,当你到达这里

 void startTimer( struct Timer* ptimer ) 

在范围内没有struct Timer (只是一个匿名结构的typedef)。 所以编译器相信你要声明一个新的类型struct Timer并使用一个指针作为参数。

实际上,这样做不会有用,因为类型只能在函数内部可见。 这将使实际上不可能从函数外部传入一个参数。

所以编译器说,虽然可能被语言所允许,但这看起来不是一个好主意!