Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dereferencing pointer to incomplete type when time.h header is already included

Tags:

c

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.

like image 536
Frank Harris Avatar asked Jun 11 '13 17:06

Frank Harris


2 Answers

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:

  • corresponded header file
  • necessary project headers
  • 3rd party libraries headers
  • standard libraries headers
  • system headers

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

like image 158
Yang Avatar answered Oct 18 '22 18:10

Yang


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.

like image 39
sth Avatar answered Oct 18 '22 17:10

sth