Reputation: 305
I'm writing a header, timedate.h, which begins as follows:
#ifndef _TIMEDATE_H_
#define _TIMEDATE_H_
int timetounixtime(int year, int month, int day, int hour, int minute, int second)
{
struct tm *time;
time->tm_year = year;
time->tm_mon = month;
time->tm_mday = day;
time->tm_hour = hour;
time->tm_min = minute;
time->tm_sec = second;
return mktime(time);
}
/*...*/
#endif
And is then included in one of my main .c files as follows:
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "timedate.h"
int main(int argv, char **argc)
{
/*...*/
}
It seems to me that this should work since time.h is included in the main code before timedate.h is called. However, when I make, I get the following errors:
XXXXXXXXXX$ make
gcc file2nav.c -o file2nav
In file included from file2nav.c:4:0:
timedate.h: In function ‘timetounixtime’:
timedate.h:10:7: error: dereferencing pointer to incomplete type
timedate.h:11:7: error: dereferencing pointer to incomplete type
timedate.h:12:7: error: dereferencing pointer to incomplete type
timedate.h:13:7: error: dereferencing pointer to incomplete type
timedate.h:14:7: error: dereferencing pointer to incomplete type
timedate.h:15:7: error: dereferencing pointer to incomplete type
Can you help me understand what's going on? I note that if I #include <time.h>
in timedate.h, the error goes away...But why? It's already included in file2nav.c.
Upvotes: 5
Views: 6038
Reputation: 36882
You need to #include <time.h>
in you timedate.h
file because the function timetounixtime
uses a struct declared in it. That function needs to know what a struct tm
is, and it doesn't unless you include time.h
. There are several other problems here though.
You need to allocate space for your tm struct as such:
struct tm *time = malloc(sizeof *time);
but since you're only using it in this one function, you should just be doing
struct tm time;
otherwise you're using invalid memory when you start assigning.
This header file should be separated into two files, additionally.
/* timedate.h */
#ifndef _TIMEDATE_H_
#define _TIMEDATE_H_
int timetounixtime(int year, int month, int day, int hour, int minute, int second);
#endif
and
/* timedate.c */
#include "timedate.h"
int timetounixtime(int year, int month, int day, int hour, int minute, int second)
{
struct tm time;
time.tm_year = year;
time.tm_mon = month;
time.tm_mday = day;
time.tm_hour = hour;
time.tm_min = minute;
time.tm_sec = second;
return mktime(time);
}
I suggest in the future you compile with gcc -Wall
. You'll get useful warnings like this one:
timedate.h:15:3: warning: implicit declaration of function 'mktime' [-Wimplicit-function-declaration]
^which means you are calling the mktime
function without ever declaring it, another symptom of forgetting time.h
Upvotes: 3
Reputation: 8170
In your file timedate.h
you use
struct tm *time;
but struct tm
is not defined yet. You need to include the header #include <time.h>
.
A second problem in your code is that you're using an uninitialized pointer time
. You can use a local variable:
struct tm time;
time.tm_year = year;
or malloc
a pointer (remember to free
):
struct tm* time = malloc(sizeof(struct tm));
A better practice, as Ryan points out, is to declare functions in .h
and define them in .c
:
/* timedate.h */
#ifndef _TIMEDATE_H_
#define _TIMEDATE_H_
int timetounixtime(int year, int month, int day, int hour, int minute, int second);
#endif
and
/* timedate.c */
#include "timedate.h"
#include <time.h>
int timetounixtime(int year, int month, int day, int hour, int minute, int second)
{
struct tm time;
time.tm_year = year;
time.tm_mon = month;
time.tm_mday = day;
time.tm_hour = hour;
time.tm_min = minute;
time.tm_sec = second;
return mktime(time);
}
You need to include all header files to make your program compile. C++ Header order suggests one possible order:
In this order you will not miss any of your header files that forgot to include libraries by their own. (Thank Josh for this point).
Upvotes: 11
Reputation: 229754
You include the wrong header, it should be <time.h>
, not <sys/time.h>
.
<sys/time.h>
probably simply doesn't define the struct you are trying to use.
Upvotes: 3
Reputation: 544
You need to include the time.h header from the header file because it won't know what the struct tm and mktime symbols are.
You would need forward declarations of those symbols in order for them to link properly when the time.h header eventually gets included from your source file.
Upvotes: 0
Reputation: 8839
time
also happens to be a system call. I'll suggest changing the variable name time
to something else so as not to cause a conflict with the system call.
Upvotes: 1