I don't understand why compiler is giving me e

2019-04-21 13:52发布

问题:

I have the following C code, which looks very correct to me. However, the clang compiler (infact gcc or any other C compiler too) thinks otherwise.

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 );
}

The compiler gives the following waring & error messages. Any idea what is wrong here?

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

回答1:

Remove the struct keyword (it's not needed since you've already typedefed the struct):

void startTimer( Timer* ptimer ) 
{
  ...

void stopTimer( Timer* ptimer ) 
{
  ...

Alternatively, remove the typedef:

struct Timer
{
    struct timeval td_start;
    struct timeval td_end;
};

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

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

For more information, see Why should we typedef a struct so often in C?



回答2:

Either you

struct Timer
{
    struct timeval td_start;
    struct timeval td_end;
};

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

Or you

typedef struct
{
    struct timeval td_start;
    struct timeval td_end;
} Timer;

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

But don't mixup.



回答3:

You created a type called Timer, just delete the word struct before the function parameters, like this, for example:

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


回答4:

The reason for the error is that, when you get here

void startTimer( struct Timer* ptimer ) 

there is no struct Timer in scope (just a typedef for an anonymous struct). So the compiler believes you want to declare a new type struct Timer and use a pointer to that as a parameter.

Actually doing that would be less than useful, as the type would just be visible inside the function. That would make it practically impossible to pass in a parameter from outside the function.

So the compiler says that, while possibly allowed by the language, this doesn't look like a good idea!