2013-06-11 67 views
5

我正在寫一個頭,timedate.h,它開始如下:提領指向不完全類型時time.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) 
{ 
/*...*/ 
} 

在我看來,這應該工作,因爲time.h包含在timedate.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中。

+1

這不是一個回溯編譯器。只需將您實際需要的文件包含在標題中即可。依靠包括命令是一個可怕的想法。 –

+0

頭文件用於函數聲明而不是函數定義。 只要想想會發生什麼,如果你包含該文件兩次。 – mohit

+0

@EdS。,我很困惑爲什麼你必須#include 在頭文件中,但你不必#include 或任何其他常用的標準庫頭文件? –

回答

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

一個更好的做法,因爲瑞恩指出,是.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提出一個可能的順序:

  • 對應的頭文件
  • 必要的項目頭
  • 第三方庫的頭
  • 標準庫的頭
  • 系統頭

在這個命令你會不要錯過任何忘記自己包含庫的頭文件。 (感謝喬希這一點)。

+0

我猜他認爲這是通過在他的主文件中包含''來定義的。 – Kninnug

+0

@Kninnug,是的,這就是我的想法,我還不明白爲什麼不是這樣。我的理解是預處理器在插入我的頭文件的文本之前將.h文件中的time.h文本插入,因此,當編譯器進入代碼的那部分時,它應該已經讀取了定義的tm。 –

+0

@楊也,我做了一個局部變量的變化。不知道我在那裏做了什麼。我需要爲我的辦公室找一臺咖啡機。 –

1

time也恰好是系統調用。我建議將變量名稱time更改爲別的,以免與系統調用產生衝突。

+0

完成。我應該知道這一點。謝謝! –

+0

這不回答OP的問題。 – alk

3

您需要在您timedate.h文件中使用#include <time.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

+0

我這樣做,編輯我的頁面。謝謝。 –

+2

誰會關心告訴我爲什麼這是downvoted? –

+0

+1提及分隔標題。 – Yang

0

的另一個症狀您需要包括來自time.h中頭頭文件,因爲它不會知道struct tm和mktime符號是什麼。

當time.h頭文件最終包含在源文件中時,您需要對這些符號進行前向聲明,以便它們正確鏈接。

2

不包括sys/time.h但是time.h

3

您包含錯誤的標題,它應該是<time.h>,而不是<sys/time.h>

<sys/time.h>可能根本沒有定義你正在嘗試使用的結構。

+0

錯誤仍然顯示,但我改變了time.h。 –

相關問題