C VS循环依赖?错误C2061 - 标识符语法错误

时间:2022-06-28 09:47:54

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的问题。