我正在编写一个标题,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
然后将其包含在我的一个主要.c文件中,如下所示:
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "timedate.h"
int main(int argv, char **argc)
{
/*...*/
}
在我看来,这应该有效,因为在调用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
你能帮我理解发生了什么吗?我注意到如果我在timedate.h中#include <time.h>
,那么错误就会消失......但为什么呢?它已经包含在file2nav.c中。
答案 0 :(得分:11)
在您的文件timedate.h
中使用
struct tm *time;
但struct tm
尚未定义。您需要包含标题#include <time.h>
。
您的代码中的第二个问题是您正在使用未初始化的指针time
。您可以使用本地变量:
struct tm time;
time.tm_year = year;
或malloc
指针(记得free
):
struct tm* time = malloc(sizeof(struct tm));
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
和
/* 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);
}
您需要包含所有头文件才能编译程序。 C++ Header order提出了一个可能的顺序:
按此顺序,您不会错过任何忘记自己包含库的头文件。 (感谢Josh这一点。)
答案 1 :(得分:3)
您需要在#include <time.h>
文件中timedate.h
,因为函数timetounixtime
使用在其中声明的结构。该函数需要知道struct tm
是什么,除非包含time.h
,否则它不会。这里还有其他一些问题。
您需要为tm结构分配空间:
struct tm *time = malloc(sizeof *time);
但由于你只是在这一个函数中使用它,你应该只是做
struct tm time;
否则在开始分配时会使用无效内存。
此头文件应另外分为两个文件。
/* timedate.h */
#ifndef _TIMEDATE_H_
#define _TIMEDATE_H_
int timetounixtime(int year, int month, int day, int hour, int minute, int second);
#endif
和
/* 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);
}
我建议您将来使用gcc -Wall
进行编译。你会收到类似这样的有用警告:
timedate.h:15:3: warning: implicit declaration of function 'mktime' [-Wimplicit-function-declaration]
^表示您在没有声明的情况下调用mktime
函数,这是忘记time.h
答案 2 :(得分:3)
您包含错误的标题,应该是<time.h>
,而不是<sys/time.h>
。
<sys/time.h>
可能只是没有定义您尝试使用的结构。
答案 3 :(得分:2)
请勿包含sys/time.h
,time.h
。
答案 4 :(得分:1)
time
也恰好是系统调用。我建议将变量名time
更改为其他名称,以免与系统调用发生冲突。
答案 5 :(得分:0)
您需要在头文件中包含time.h头文件,因为它不知道struct tm和mktime符号是什么。
当最终从源文件中包含time.h标头时,您需要对这些符号进行前向声明,以便它们正确链接。