远期声明静态C结构实例C ++ [英] Forward declaring static C struct instances in C++

查看:162
本文介绍了远期声明静态C结构实例C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个code发电机,好了,实际上是一个数据发生器,将生产数据这种形式(当然实际的数据结构更为精细)的结构:

I'm writing a code generator, well, actually a data generator that will produce data structures of this form (obviously the actual data structures are much more elaborate):

typedef struct Foo {
  int a;
  struct Foo* foo;
} Foo;

extern Foo f1;
extern Foo f2;

Foo f1 = {1, &f2};
Foo f2 = {2, &f1};

这是便携式,因为我已经尝试了所有的C和C ++编译器。

This is portable for all C and C++ compilers I have tried.

我想转发声明这些结构的实例为静态,以免污染全局变量空间,如:

I would like to forward declare these struct instances as static so as not to pollute the global variable space, as in:

typedef struct Foo {
  int a;
  struct Foo* foo;
} Foo;

static Foo f1;
static Foo f2;

static Foo f1 = {1, &f2};
static Foo f2 = {2, &f1};

虽然这个作品用gcc,可能所有的C编译器,上面的code不带编译错误C ++编译器和结果工作:

Although this works with gcc and probably all C compilers, the above code does not work with C++ compilers and results in a compile error:

error: redefinition of ‘Foo f1’
error: ‘Foo f1’ previously declared

我明白这是为什么用C ++发生。有一个简单的解决办法,不使用code运行时实现是移植到所有C ++编译器,而不诉诸使用C编译器编译某些文件同样的效果涉及?

I understand why this is happening in C++. Is there a simple workaround that does not involve using code at runtime to achieve the same effect that is portable to all C++ compilers without resorting to using a C compiler to compile certain files?

推荐答案

这似乎有类似的效果乔希的回答,但较少的复杂性:

This seems to have a similar effect to Josh's answer, but with less complexity:

#ifdef __cplusplus
namespace {
    extern Foo f1;
    extern Foo f2;

    Foo f1 = {1, &f2};
    Foo f2 = {2, &f1};
}
#else
    static Foo f1;
    static Foo f2;

    Foo f1 = {1, &f2};
    Foo f2 = {2, &f1};
#endif

当编译为C ++,对F1和F2的extern定义暴露与外部可连接符号的目标文件中;然而,因为它们是一个匿名命名空间中的符号被以这样的方式,他们将不会与来自另一翻译单位符号冲突错位内

When compiled for C++, the extern definitions for f1 and f2 are exposed in the object file with an externally linkable symbol; however, because they are inside an anonymous namespace the symbols are mangled in such a way that they will not conflict with symbols from another translation unit.

使用宏魔术,你可以设定让这里只有一个地方,F1和F2的声明和定义,但如果这是正在发生机械有可能没有太多的理由这样做。

With macro magic you could set things up so there's only one place where f1 and f2 are declared and defined, but if this is being generated mechanically there's probably not much reason to do that.

是这样的:

#ifdef __cplusplus
#define START_PRIVATES namespace {
#define END_PRIVATES   }
#define PRIVATE extern
#else
#define START_PRIVATES 
#define END_PRIVATES   
#define PRIVATE static
#endif

START_PRIVATES
    PRIVATE Foo f1;
    PRIVATE Foo f2;

    Foo f1 = {1, &f2};
    Foo f2 = {2, &f1};
END_PRIVATES

这篇关于远期声明静态C结构实例C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆