C的C ++文件中正确的前向定义包括

时间:2017-05-20 06:39:22

标签: c++ c

我有以下代码,在x.cpp,g ++ 5.3.0中的最后一行编译conflicting declaration 'typedef struct THE_TYPE_STRUCT THE_TYPE'y.h时抛出编译错误:

// x.h file
struct THE_TYPE;

class C{
        THE_TYPE * t;    
};

// x.cpp file
#include "x.h"

extern "C"{
#include "y.h"
}

// y.h file
struct THE_TYPE_STRUCT {
    int x;
};

typedef struct THE_TYPE_STRUCT THE_TYPE;

文件y.h是一个C头,由于名称与其他头文件冲突,因此无法包含在头x.h的开头,因此我必须为{{1 }}。似乎它并不完全正确。 如何正确完成?

3 个答案:

答案 0 :(得分:1)

C与C ++不同,并且有不同的规则(例如,typedef struct THE_TYPE THE_TYPE;无用 - 在C ++中是隐式的,但在C中是有意义的。)

您应该生成预处理表单(例如使用g++ -C -E x.cpp > x.ii)然后进行研究。一个可能的技巧是删除行信息(从#开始),运行
g++ -C -E x.cpp | grep -v '^#' > x.ii然后使用g++ -Wall -c x.ii重新编译,并查看x.ii中的错误位置

在不知道所涉及的实际文件的情况下,我们无法帮助(例如某些文件可能有一些#define THE_TYPE)。

  

我该如何正确地做到这一点?

在C ++中,您可能会使用namespace - s(特别是在您自己的文件中)并避免使用宏。

在C中,您可能应该编辑文件,我建议在您自己的代码中为每个公共名称添加一个公共前缀。您可以从GTK获取灵感,其中每个名称都以GtkGTK_GTK等开头......

通常,您需要一些一致的命名约定,并且您可能需要编辑所有文件。

答案 1 :(得分:0)

更改

struct THE_TYPE_STRUCT {
    int x;
};

typedef struct THE_TYPE_STRUCT THE_TYPE;

typedef struct THE_TYPE_STRUCT {
    int x;
}THE_TYPE;

答案 2 :(得分:0)

我在当前项目中使用以下方案将一些代码混合到代码库中:

basedecl.h (随处可见):

// [...]
#ifdef __cplusplus
#  define pocaslibs___cdecl extern "C"
#  define DECLDATA
#  define C_CLASS_DECL(t) struct t
#  define C_ENUM_DECL(t) enum t
#else
#  define pocaslibs___cdecl
#  define DECLDATA extern
#  define C_CLASS_DECL(t) typedef struct t t
#  define C_ENUM_DECL(t) typedef enum t t
#endif
// [...]

正向声明struct类型(也用于"私有"类型):

C_CLASS_DECL(PG_Menu);
C_CLASS_DECL(PG_Window);

宣布"公众" struct种类:

C_CLASS_DECL(PG_Bounds);
struct PG_Bounds
{
    unsigned int x;
    unsigned int y;
    unsigned int width;
    unsigned int height;
};

对两种语言都很有效。该宏名为C_CLASS_DECL,因为在我的代码库中,这实际上用于在中创建OO类。如果你的用例与OO无关,那么最好考虑一个更好的名字;)