我有以下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&错误消息。知道这里有什么问题吗?
./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 )
答案 0 :(得分:16)
删除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 )
{
...
答案 1 :(得分:4)
你要么
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 );
}
但不要混淆。
答案 2 :(得分:3)
你创建了一个名为Timer的类型,只需在函数参数之前删除单词struct,例如:
void startTimer( Timer* ptimer )
{
gettimeofday( &(ptimer->td_start), NULL );
}
答案 3 :(得分:2)
错误的原因是,当你到达时
void startTimer( struct Timer* ptimer )
范围内没有struct Timer
(只是匿名结构的typedef)。因此,编译器认为您要声明 new 类型struct Timer
并使用指针作为参数。
实际上这样做不太有用,因为该类型只是在内部函数中可见。这将使从外部函数传递参数几乎不可能。
所以编译器说,尽管语言可能允许,但这看起来不是一个好主意!