10

我有以下 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 );
}

编译器给出以下警告和错误消息。知道这里有什么问题吗?

./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 )
4

4 回答 4

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 ) 
{
  ...

有关更多信息,请参阅为什么我们应该在 C 中如此频繁地对结构进行类型定义?

于 2012-05-15T14:44:42.353 回答
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 );
}

但不要混淆。

于 2012-05-15T14:45:38.593 回答
3

你创建了一个名为 Timer 的类型,只需删除函数参数前的 struct 一词,如下所示,例如:

void startTimer( Timer* ptimer ) 
{
    gettimeofday( &(ptimer->td_start), NULL );
}
于 2012-05-15T14:45:42.383 回答
2

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

void startTimer( struct Timer* ptimer ) 

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

实际上这样做并没有多大用处,因为类型只会在函数内部可见。这将使得从函数外部传入参数几乎是不可能的。

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

于 2012-05-15T16:22:11.483 回答