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 に答える