当已包含time.h标头时,取消引用指向不完整类型的指针

Fra*_*ris 5 c

我正在写一个标题,timedate.h,其开头如下:

#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
Run Code Online (Sandbox Code Playgroud)

然后将其包含在我的一个主要.c文件中,如下所示:

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "timedate.h"

int main(int argv, char **argc)
{
/*...*/
}
Run Code Online (Sandbox Code Playgroud)

在我看来,这应该工作,因为在调用timedate.h之前,time.h包含在主代码中.但是,当我制作时,我收到以下错误:

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
Run Code Online (Sandbox Code Playgroud)

你能帮我理解发生了什么吗?我注意到,如果我#include <time.h>在timedate.h中,错误就会消失......但为什么呢?它已经包含在file2nav.c中.

Yan*_*ang 11

在您timedate.h使用的文件中

struct tm *time;
Run Code Online (Sandbox Code Playgroud)

struct tm尚未定义.您需要包含标题#include <time.h>.

代码中的第二个问题是您使用的是未初始化的指针time.您可以使用局部变量:

struct tm time;
time.tm_year = year;
Run Code Online (Sandbox Code Playgroud)

malloc指针(记得free):

struct tm* time = malloc(sizeof(struct tm));
Run Code Online (Sandbox Code Playgroud)

正如Ryan所指出的,更好的做法是将函数声明.h定义它们.c:

/* timedate.h */
#ifndef _TIMEDATE_H_
#define _TIMEDATE_H_

int timetounixtime(int year, int month, int day, int hour, int minute, int second);

#endif
Run Code Online (Sandbox Code Playgroud)

/* 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);
}
Run Code Online (Sandbox Code Playgroud)

您需要包含所有头文件以使您的程序编译.C++标题顺序提示一个可能的顺序:

  • 相应的头文件
  • 必要的项目标题
  • 第三方库标题
  • 标准库头
  • 系统标题

按此顺序,您将不会错过任何忘记自己包含库的头文件.(感谢Josh这一点).

  • @FrankHarris:`<time.h>`和`<sys/time.h>`是不同的文件. (2认同)