[英]How to fix incomplete type error caused by struct inside struct in C?
我正在開發一個使用我自己創建的多個庫的項目。 其中一些庫相互依賴,為了避免循環依賴問題,我使用了前向聲明頭方法,該方法包括為前向聲明創建一個單獨的文件,如本文的一個答案中所述: 解決由於類之間的循環依賴導致的構建錯誤。
在某些標頭中,我創建了包含指向其他標頭中結構的指針的結構,並且沒有問題。 但是,現在我需要聲明一些包含結構而不是結構指針的結構。 例如,這些是我在名為 Capa2.h 的文件中所做的聲明。
#include "Capa2_fwd.h"
#include "Net_fwd.h"
#include "Grafico.h"
#define TAM_MAX_PAYLOAD 248
#pragma pack(push, 1)
struct cab_arp_ {
short tipo_hw;
short tipo_proto;
char lon_dir_hw;
char lon_dir_proto;
short cod_op;
dir_mac_t mac_origen;
unsigned int ip_origen;
dir_mac_t mac_destino;
unsigned int ip_destino;
};
struct cab_ethernet_ {
dir_mac_t mac_destino;
dir_mac_t mac_origen;
short type;
char payload[TAM_MAX_PAYLOAD];
unsigned int FCS;
};
#pragma pack(pop)
struct entrada_arp_ {
dir_ip_t dir_ip;
dir_mac_t dir_mac;
char nombre_if[16];
};
struct tabla_arp_ {
Lista_t *entradas_arp;
};
這些是 Capa2_fwd.h 中的前向聲明。
typedef struct cab_arp_ cab_arp_t;
typedef struct cab_ethernet_ cab_ethernet_t;
typedef struct entrada_arp_ entrada_arp_t;
typedef struct tabla_arp_ tabla_arp_t;
我收到這些錯誤。
In file included from ./inc/Net.h:10, from ./inc/Grafico.h:7, from prueba.c:2:
./inc/Capa2.h:18:12: error: field ‘mac_origen’ has incomplete type
18 | dir_mac_t mac_origen;
./inc/Capa2.h:20:12: error: field ‘mac_destino’ has incomplete type
20 | dir_mac_t mac_destino;
./inc/Capa2.h:25:12: error: field ‘mac_destino’ has incomplete type
25 | dir_mac_t mac_destino;
./inc/Capa2.h:26:12: error: field ‘mac_origen’ has incomplete type
26 | dir_mac_t mac_origen;
./inc/Capa2.h:35:11: error: field ‘dir_ip’ has incomplete type
35 | dir_ip_t dir_ip;
./inc/Capa2.h:36:12: error: field ‘dir_mac’ has incomplete type
36 | dir_mac_t dir_mac;
導致錯誤的類型在 Net_fwd.h 中聲明
typedef struct dir_ip_ dir_ip_t;
typedef struct dir_mac_ dir_mac_t;
typedef struct prop_nodo_ prop_nodo_t;
typedef struct prop_intf_ prop_intf_t;
並且結構在 Net.h 中聲明
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "Grafico.h"
#include "Net_fwd.h"
#include "Capa2.h"
#define TAM_DIR_MAC 6
#define TAM_DIR_IP 16
#pragma pack(push, 1)
typedef struct dir_ip_ {
char dir_ip[TAM_DIR_IP];
} dir_ip_t;
typedef struct dir_mac_ {
char dir_mac[TAM_DIR_MAC];
} dir_mac_t;
#pragma pack (pop)
struct prop_nodo_ {
bool tiene_dir_loopback;
dir_ip_t dir_loopback;
};
struct prop_intf_ {
bool tiene_dir_ip;
dir_ip_t dir_ip;
dir_mac_t dir_mac;
char mascara;
};
我知道如果我想將結構放入結構中,前向聲明是不夠的,但我不知道如何解決這個問題。
當您聲明一個變量/字段是指向結構類型的指針時,編譯器不需要知道定義,直到您取消引用代碼中的指針,因為變量/字段的大小為 8 個字節(在 64 位上)建築學)。 當您將變量/字段聲明為結構體類型時,編譯器必須知道結構體的大小是多少才能分配足夠的內存。 重命名結構的 typedef 可以向前,因為不需要大小。 但是如果你想用結構化類型聲明字段,那么結構聲明必須按拓撲順序出現。 所以編譯器必須在 Capa2.h 之前看到 Net.h。
更新
因此,根據您的評論,唯一的方法是更改您包含所有內容的方式。 以下場景是否符合您的需求?
首先,忘記前向聲明,然后:
卡帕2.h
#ifndef _INC_CAPA2_H
#define _INC_CAPA2_H
#include "Net.h"
#define TAM_MAX_PAYLOAD 248
#pragma pack(push, 1)
struct cab_arp_ {
short tipo_hw;
short tipo_proto;
char lon_dir_hw;
char lon_dir_proto;
short cod_op;
dir_mac_t mac_origen;
unsigned int ip_origen;
dir_mac_t mac_destino;
unsigned int ip_destino;
};
struct cab_ethernet_ {
dir_mac_t mac_destino;
dir_mac_t mac_origen;
short type;
char payload[TAM_MAX_PAYLOAD];
unsigned int FCS;
};
#pragma pack(pop)
struct entrada_arp_ {
dir_ip_t dir_ip;
dir_mac_t dir_mac;
char nombre_if[16];
};
#endif
凈小時
#ifndef _INC_NET_H
#define _INC_NET_H
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "Capa2.h"
#define TAM_DIR_MAC 6
#define TAM_DIR_IP 16
#pragma pack(push, 1)
typedef struct dir_ip_ {
char dir_ip[TAM_DIR_IP];
} dir_ip_t;
typedef struct dir_mac_ {
char dir_mac[TAM_DIR_MAC];
} dir_mac_t;
#pragma pack (pop)
struct prop_nodo_ {
bool tiene_dir_loopback;
dir_ip_t dir_loopback;
};
struct prop_intf_ {
bool tiene_dir_ip;
dir_ip_t dir_ip;
dir_mac_t dir_mac;
char mascara;
};
#endif
主程序
#include "Capa2.h"
#include "Net.h"
int _tmain(int argc, _TCHAR* argv[])
{
cab_arp_ x;
prop_intf_ y;
return 0;
}
這對我來說是成功編譯的,除非你的項目有一些你沒有提到的其他復雜性,否則對你的也應該沒問題。
舊答案
如果不知道所有標題的內容,就很難就此提出建議。 我想到的第一件事是使用頭球后衛。
將每個頭文件的內容包裝在#ifndef
指令中,如下所示。 確保為每個標頭使用不同的名稱( _INC_CAPA2_FWD
、 _INC_NET_FWD
等):
#ifndef _INC_CAPA2_FWD
#define _INC_CAPA2_FWD
// header content goes here
#endif // _INC_CAPA2_FWD
這樣,您可能也不需要進行前向聲明。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.