I'm developing small project in C using Visual Studio. To avoid multiple includes I'm using include guards.
我正在使用Visual Studio在C中开发小项目。为了避免多重包含,我正在使用包含警戒。
I'm getting lot of errors including this one:
file: collections.h
error: C2061
description: syntax error: identifier 'Terminal'
我收到很多错误,包括这一个:file:collections.h错误:C2061描述:语法错误:标识符'终端'
synt_analysis.c
synt_analysis.c
#include <string.h>
#include "headers\synt_analysis.h"
synt_analysis.h
synt_analysis.h
#ifndef SYNT_ANALYSIS_H
#define SYNT_ANALYSIS_H
#include "collections.h"
typedef enum {
...
}TType;
typedef enum {
...
}NTType;
typedef struct {
TType type;
...
}Terminal;
void push_terminal(Terminal terminal, cStack *stack);
#endif
collections.h
collections.h
#ifndef COLLECTIONS_H
#define COLLECTIONS_H
#include "synt_analysis.h"
typedef union {
int error;
Terminal terminal;
NTType nttype;
}cItemData;
typedef struct {
char *type;
cItemData content;
}cItem;
typedef struct {
unsigned cap;
unsigned used;
cItem *items;
}cStack;
#endif
collections provides cStack
, which can store Terminal
defined by synt_analysis.
synt_analysis uses cStack
in function push_terminal
- which pushes Terminal
on the Stack. This function exists to reduce amount of code needed (it creates new Terminal
and pushes it on cStack
).
collections提供了cStack,它可以存储由synt_analysis定义的终端。 synt_analysis在函数push_terminal中使用cStack - 它在栈上推送终端。此函数用于减少所需的代码量(它创建新的终端并将其推送到cStack)。
2 个解决方案
#1
2
Because this problem cannot be simply solved by forward declaration (compiler needs to know size of incomplete struct type - it's used as one option of union), the solution is to create another header file, which will break circular dependency.
因为这个问题不能通过前向声明简单地解决(编译器需要知道不完整结构类型的大小 - 它被用作联合的一个选项),解决方案是创建另一个头文件,这将破坏循环依赖。
New file synt_structures.h
新文件synt_structures.h
#ifndef SYNT_STRUCTURES_H
#define SYNT_STRUCTURES_H
#include "lex_analysis.h"
typedef enum {
...
}NTType;
typedef enum {
...
}TType;
typedef struct {
TType type;
...
}Terminal;
#endif
synt_analysis.h includes:
synt_analysis.h包括:
#include "collections.h"
#include "synt_structures.h"
collections.h includes:
collections.h包括:
#include "synt_structures.h"
That breaks the cycle.
这打破了周期。
#2
0
EDIT: The following doesn't actually solve the problem in this case, but I left it here as a useful technique for solving some circular dependencies.
编辑:以下实际上并没有解决这种情况下的问题,但我把它留在这里作为解决一些循环依赖的有用技术。
Since cStack
is only used as part of a pointer type within "synt_analysis.h", it can be an incomplete type within that header file. In order to make it an incomplete type, you need a tag to refer to it.
由于cStack仅用作“synt_analysis.h”中指针类型的一部分,因此它可以是该头文件中的不完整类型。为了使其成为不完整的类型,您需要一个标签来引用它。
In "collections.h", add a tag to the struct
that is used in the definition of the cStack
type:
在“collections.h”中,将标记添加到cStack类型定义中使用的结构中:
typedef struct cStack {
unsigned cap;
unsigned used;
cItem *items;
}cStack;
In "synt_analysis.h" define the same type as an incomplete type:
在“synt_analysis.h”中定义与不完整类型相同的类型:
typedef struct cStack cStack;
EDIT: As mentioned above, this doesn't actually solve the OP's problem.
编辑:如上所述,这实际上并没有解决OP的问题。
#1
2
Because this problem cannot be simply solved by forward declaration (compiler needs to know size of incomplete struct type - it's used as one option of union), the solution is to create another header file, which will break circular dependency.
因为这个问题不能通过前向声明简单地解决(编译器需要知道不完整结构类型的大小 - 它被用作联合的一个选项),解决方案是创建另一个头文件,这将破坏循环依赖。
New file synt_structures.h
新文件synt_structures.h
#ifndef SYNT_STRUCTURES_H
#define SYNT_STRUCTURES_H
#include "lex_analysis.h"
typedef enum {
...
}NTType;
typedef enum {
...
}TType;
typedef struct {
TType type;
...
}Terminal;
#endif
synt_analysis.h includes:
synt_analysis.h包括:
#include "collections.h"
#include "synt_structures.h"
collections.h includes:
collections.h包括:
#include "synt_structures.h"
That breaks the cycle.
这打破了周期。
#2
0
EDIT: The following doesn't actually solve the problem in this case, but I left it here as a useful technique for solving some circular dependencies.
编辑:以下实际上并没有解决这种情况下的问题,但我把它留在这里作为解决一些循环依赖的有用技术。
Since cStack
is only used as part of a pointer type within "synt_analysis.h", it can be an incomplete type within that header file. In order to make it an incomplete type, you need a tag to refer to it.
由于cStack仅用作“synt_analysis.h”中指针类型的一部分,因此它可以是该头文件中的不完整类型。为了使其成为不完整的类型,您需要一个标签来引用它。
In "collections.h", add a tag to the struct
that is used in the definition of the cStack
type:
在“collections.h”中,将标记添加到cStack类型定义中使用的结构中:
typedef struct cStack {
unsigned cap;
unsigned used;
cItem *items;
}cStack;
In "synt_analysis.h" define the same type as an incomplete type:
在“synt_analysis.h”中定义与不完整类型相同的类型:
typedef struct cStack cStack;
EDIT: As mentioned above, this doesn't actually solve the OP's problem.
编辑:如上所述,这实际上并没有解决OP的问题。