Reputation: 21655
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 )
Upvotes: 10
Views: 14532
Reputation: 92331
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!
Upvotes: 2
Reputation: 500733
Remove the struct
keyword (it's not needed since you've already typedef
ed 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?
Upvotes: 16
Reputation: 1480
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 );
}
Upvotes: 3
Reputation: 37467
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.
Upvotes: 4