正向声明静态变量 [英] Forward declaration of static variable

查看:99
本文介绍了正向声明静态变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C项目中遇到以下问题(但是还需要使用C ++编译器编译
)。我正在使用虚拟功能表,

在头文件中看起来像这样:

typedef struct device_t {

const device_backend_t * backend;

...

} device_t;


typedef struct device_backend_t {

int(* read)(device_t * device,/ * parameters * /);

int(* write)(device_t * device,/ * parameters * /);

...

} device_backend_t;


现在当我想实现一个新的后端时,我写了必要的

源文件中的函数:


int mydevice_read(device_t * device,/ * parameters * /)

{

.. 。

}


int mydevice_write(device_t * device,/ * parameters * /)

{

...

}


static const device_backend_t mydevice_backend = {

mydevice_read,

mydevice_write,

...

};


到目前为止没问题,但是在一些这些功能,我需要

才能访问mydevice_backend。变量。例如,检查

后端指针是否正确。我怎样才能正确地声明这个

变量?

当我添加


static const device_backend_t reefnet_sensuspro_device_backend;


到我的源文件的顶部,它适用于gcc编译器,但我是

不确定这是否有效根据C(或C ++)标准。它肯定不会用msvc编译(在C ++模式下)
。它抱怨

重新定义。


如何才能完成这项工作?我可以移动

" mydevice_backend"的定义。变量到源文件的顶部并转发

声明结构中的每个函数,但是能够转发

声明变量本身会更加优雅。 />

I have the following problem in a C project (but that also needs to
compile with a C++ compiler). I''m using a virtual function table, that
looks like this in the header file:

typedef struct device_t {
const device_backend_t *backend;
...
} device_t;

typedef struct device_backend_t {
int (*read) (device_t *device, /* parameters */);
int (*write) (device_t *device, /* parameters */);
...
} device_backend_t;

Now when I want to implement a new backend, I write the necessary
functions in the source file:

int mydevice_read (device_t *device, /* parameters */)
{
...
}

int mydevice_write (device_t *device, /* parameters */)
{
...
}

static const device_backend_t mydevice_backend = {
mydevice_read,
mydevice_write,
...
};

So far no problem, but in a number of those functions, I need to have
access to the "mydevice_backend" variable. For instance to check whether
the backend pointer is the correct one. How can I forward declare this
variable properly?

When I add

static const device_backend_t reefnet_sensuspro_device_backend;

to the top of my source file, it works with the gcc compiler, but I''m
not sure this is valid according to the C (or C++) standard. It
certainly doesn''t compile with msvc (in C++ mode). It complains about a
redefinition.

How can I make this work? I could move the definition of the
"mydevice_backend" variable to the top of the source file and forward
declare each function inside the structure, but being able to forward
declare the variable itself would be much more elegant.

推荐答案

Jef Driesen< je ******** @ hotmail.com.invalidwrites:
Jef Driesen <je********@hotmail.com.invalidwrites:

我在C项目中遇到以下问题(但是还需要使用C ++编译器编译
)。我正在使用虚拟功能表,

在头文件中看起来像这样:

typedef struct device_t {

const device_backend_t * backend;

...

} device_t;


typedef struct device_backend_t {

int(* read)(device_t * device,/ * parameters * /);

int(* write)(device_t * device,/ * parameters * /);

...

} device_backend_t;


现在当我想实现一个新的后端时,我写了必要的

源文件中的函数:


int mydevice_read(device_t * device,/ * parameters * /)

{

.. 。

}


int mydevice_write(device_t * device,/ * parameters * /)

{

...

}


static const device_backend_t mydevice_backend = {

mydevice_read,

mydevice_write,

...

};


到目前为止还没有问题lem,但是在其中一些功能中,我需要访问mydevice_backend和mydevice_backend。变量。例如,检查

后端指针是否正确。我如何转发

正确声明这个变量?

当我添加


static const device_backend_t reefnet_sensuspro_device_backend;
I have the following problem in a C project (but that also needs to
compile with a C++ compiler). I''m using a virtual function table, that
looks like this in the header file:

typedef struct device_t {
const device_backend_t *backend;
...
} device_t;

typedef struct device_backend_t {
int (*read) (device_t *device, /* parameters */);
int (*write) (device_t *device, /* parameters */);
...
} device_backend_t;

Now when I want to implement a new backend, I write the necessary
functions in the source file:

int mydevice_read (device_t *device, /* parameters */)
{
...
}

int mydevice_write (device_t *device, /* parameters */)
{
...
}

static const device_backend_t mydevice_backend = {
mydevice_read,
mydevice_write,
...
};

So far no problem, but in a number of those functions, I need to have
access to the "mydevice_backend" variable. For instance to check
whether the backend pointer is the correct one. How can I forward
declare this variable properly?

When I add

static const device_backend_t reefnet_sensuspro_device_backend;



我想你的意思


static const device_backend_t mydevice_backend;


At至少这是你在上面和下面使用的名字。

I think you mean

static const device_backend_t mydevice_backend;

At least that is the name you use above and below.


到源文件的顶部,它适用于gcc编译器,但我是

不确定这是否符合C(或C ++)标准。它肯定不会用msvc编译(在C ++模式下)
。它抱怨重新定义


to the top of my source file, it works with the gcc compiler, but I''m
not sure this is valid according to the C (or C++) standard. It
certainly doesn''t compile with msvc (in C++ mode). It complains about
a redefinition.



你可以在comp.lang.c ++中得到一个更好的答案,因为整个区域是

其中有一些微妙但重要的区别在C和

C ++之间。如果你需要代码通过C ++编译器,那么你就可以编写C ++(不管它看起来像C!)你需要C ++

专家。


我说你在C模式的MSVC上失败了我会写的:这可能是需要确切细节的b $ b,所以请构建一个最小的

编译一个但不编译其他编译器的例子(你有99%

已经有你概述的那个)。


我说这个的原因是在顶部对于

这个问题还不够清楚,因为静态结构的声明是什么是

调用(在C中)一个暂定的定义和特殊规则适用。由于

它有内部链接,它必须是一个完整的类型(按标准)

但gcc接受它即使不完整(允许 - 有

没有要求提供诊断信息。


[事实上,在我看到你的在C ++模式下之前,我已经写过了备注。我怀疑你不需要C'对这个问题的回答。]

You may get a better answer in comp.lang.c++ since this whole area is
one in which there are subtle but important differences between C and
C++. If you need the code to pass through a C++ compiler, then you
are writing C++ (no matter how much it looks like C!) and you need C++
experts.

I you had said it failed on MSVC in C mode I would have written: It is
likely that exact details are required so please construct a minimal
example that compiles in one but not the other compiler (you are 99%
there already with what you outlined).

The reason I say this is that "at the top" is not clear enough for
this problem because the declaration of the static struct is what is
called (in C) a tentative definition and special rules apply. Since
it has internal linkage, it must be a complete type (by the standard)
but gcc accepts it even when incomplete (it is allowed to -- there is
no requirement for a diagnostic message).

[In fact I wrote that before I saw your "in C++ mode" remark. I
suspect you don''t need C''s answer to this question.]


我怎样才能做到这一点?我可以移动

" mydevice_backend"的定义。变量到源文件的顶部并转发

声明结构中的每个函数,但是能够转发

声明变量本身会更优雅。
How can I make this work? I could move the definition of the
"mydevice_backend" variable to the top of the source file and forward
declare each function inside the structure, but being able to forward
declare the variable itself would be much more elegant.



你可以在C中,但可能不在C ++中。 C ++人可以告诉你。


-

Ben。

You can in C, but maybe not in C++. The C++ people can tell you.

--
Ben.


8月23日,凌晨2:57,Jef Driesen< jefdrie ... @ hotmail.com.invalid>

写道:
On Aug 23, 2:57 am, Jef Driesen <jefdrie...@hotmail.com.invalid>
wrote:

我有以下C项目中的问题(但是还需要使用C ++编译器编译
)。我正在使用虚拟功能表,

在头文件中看起来像这样:

typedef struct device_t {

const device_backend_t * backend;

...


} device_t;


typedef struct device_backend_t {

int(* read)(device_t * device,/ * parameters * /);

int(* write)(device_t * device,/ * parameters * /);

...


} device_backend_t;
I have the following problem in a C project (but that also needs to
compile with a C++ compiler). I''m using a virtual function table, that
looks like this in the header file:

typedef struct device_t {
const device_backend_t *backend;
...

} device_t;

typedef struct device_backend_t {
int (*read) (device_t *device, /* parameters */);
int (*write) (device_t *device, /* parameters */);
...

} device_backend_t;



.....

.....


到目前为止没有问题,但在许多这些函数中,我需要

才能访问mydevice_backend。变量。例如,检查

后端指针是否正确。我怎样才能正确地声明这个

变量?

当我添加


static const device_backend_t reefnet_sensuspro_device_backend;


到我的源文件的顶部,它适用于gcc编译器,但我是

不确定这是否有效根据C(或C ++)标准。它肯定不会用msvc编译(在C ++模式下)
。它抱怨重新定义


So far no problem, but in a number of those functions, I need to have
access to the "mydevice_backend" variable. For instance to check whether
the backend pointer is the correct one. How can I forward declare this
variable properly?

When I add

static const device_backend_t reefnet_sensuspro_device_backend;

to the top of my source file, it works with the gcc compiler, but I''m
not sure this is valid according to the C (or C++) standard. It
certainly doesn''t compile with msvc (in C++ mode). It complains about a
redefinition.



为了清楚起见,g ++是否接受,或者只是gcc?


在C(99)中,这是暂定的;它可以使用以后的

初始化程序来进行实际的初始化。 [C99标准:6.9.2

第2段]暂定定义从C +

+98 [资料性附件C.2.2第1段]中删除;这确实是用C ++重新定义的。


根据你的描述,我认为extern不是一个好主意

(这应该适用于在
C和C ++中向前声明一个文件范围变量)。

Just to be clear, does g++ accept that, or just gcc?

In C(99), that is a tentative definition; it can use a later
initializer to do the actual initialization. [C99 standard: 6.9.2
paragraph 2] Tentative definitions were intentionally removed from C+
+98 [Informative Annex C.2.2 paragraph 1]; this indeed is a
redefinition in C++.

From what you describe, I don''t think extern would be a good idea
(that should work for forward-declaring a file-scope variable in both
C and C++).


我该怎么办?让这个工作吗?我可以移动

" mydevice_backend"的定义。变量到源文件的顶部并转发

声明结构中的每个函数,但是能够转发

声明变量本身会更优雅。
How can I make this work? I could move the definition of the
"mydevice_backend" variable to the top of the source file and forward
declare each function inside the structure, but being able to forward
declare the variable itself would be much more elegant.



假设static是正确的链接,我只是向前声明

函数是可移植的。

Assuming static is the correct linkage, I''d just forward-declare the
functions to be portable.


Ben Bacarisse写道:
Ben Bacarisse wrote:

Jef Driesen< je ******** @ hotmail.com.invalidwrites:
Jef Driesen <je********@hotmail.com.invalidwrites:

>我在C项目中遇到以下问题(但是还需要使用C ++编译器进行编译)。我正在使用虚拟功能表,在头文件中看起来像这样:

typedef struct device_t {
const device_backend_t * backend;
..
} device_t;

typedef struct device_backend_t {
int(* read)(device_t * device,/ * parameters * /);
int(* write) (device_t * device,/ * parameters * /);
...
} device_backend_t;

现在,当我想实现一个新的后端时,我写了必要的
int mydevice_read(device_t * device,/ * parameters * /)
{
...
}

int mydevice_write(device_t * device,/ * parameters * /)
{
...

静态const device_backend_t mydevice_backend = {
mydevice_read,
mydevice_write,
......
};

到目前为止没有问题,但在其中一些功能中,我需要
访问mydevice_backend变量。例如,检查
后端指针是否正确。我怎样才能正确地声明这个变量?

当我添加

static const device_backend_t reefnet_sensuspro_device_backend;
>I have the following problem in a C project (but that also needs to
compile with a C++ compiler). I''m using a virtual function table, that
looks like this in the header file:

typedef struct device_t {
const device_backend_t *backend;
...
} device_t;

typedef struct device_backend_t {
int (*read) (device_t *device, /* parameters */);
int (*write) (device_t *device, /* parameters */);
...
} device_backend_t;

Now when I want to implement a new backend, I write the necessary
functions in the source file:

int mydevice_read (device_t *device, /* parameters */)
{
...
}

int mydevice_write (device_t *device, /* parameters */)
{
...
}

static const device_backend_t mydevice_backend = {
mydevice_read,
mydevice_write,
...
};

So far no problem, but in a number of those functions, I need to have
access to the "mydevice_backend" variable. For instance to check
whether the backend pointer is the correct one. How can I forward
declare this variable properly?

When I add

static const device_backend_t reefnet_sensuspro_device_backend;



我想你的意思


static const device_backend_t mydevice_backend;


At至少这是你在上面和下面使用的名字。


I think you mean

static const device_backend_t mydevice_backend;

At least that is the name you use above and below.



你是对的。这是一个复制粘贴错误。

You''re correct. This was a copy-and-paste error.


>到我的源文件顶部,它适用于gcc编译器,但我不确定这是否符合C(或C ++)标准。它肯定不会用msvc编译(在C ++模式下)。它抱怨重新定义。
>to the top of my source file, it works with the gcc compiler, but I''m
not sure this is valid according to the C (or C++) standard. It
certainly doesn''t compile with msvc (in C++ mode). It complains about
a redefinition.



你可以在comp.lang.c ++中得到一个更好的答案,因为整个区域是

其中有一个微妙但重要的区别在C和

C ++之间。如果你需要代码通过C ++编译器,那么你就可以编写C ++(不管它看起来像C!)你需要C ++

专家。


我说你在C模式的MSVC上失败了我会写的:这可能是需要确切细节的b $ b,所以请构建一个最小的

编译一个但不编译其他编译器的例子(你有99%

已经有你概述的那个)。


我说这个的原因是在顶部对于

这个问题还不够清楚,因为静态结构的声明是什么是

调用(在C中)一个暂定的定义和特殊规则适用。由于

它有内部链接,它必须是一个完整的类型(按标准)

但gcc接受它即使不完整(允许 - 有

不要求诊断消息)。


You may get a better answer in comp.lang.c++ since this whole area is
one in which there are subtle but important differences between C and
C++. If you need the code to pass through a C++ compiler, then you
are writing C++ (no matter how much it looks like C!) and you need C++
experts.

I you had said it failed on MSVC in C mode I would have written: It is
likely that exact details are required so please construct a minimal
example that compiles in one but not the other compiler (you are 99%
there already with what you outlined).

The reason I say this is that "at the top" is not clear enough for
this problem because the declaration of the static struct is what is
called (in C) a tentative definition and special rules apply. Since
it has internal linkage, it must be a complete type (by the standard)
but gcc accepts it even when incomplete (it is allowed to -- there is
no requirement for a diagnostic message).



使用在顶部我的意思是在device_t和

device_backend_t类型的定义之后,但是在mydevice_read之前,

mydevice_write函数。

With "at the top" I meant after the definition of device_t and
device_backend_t types, but right before the mydevice_read,
mydevice_write functions.


[事实上,在我看到你的在C ++模式下之前,我已经写过了备注。我怀疑你不需要C'对这个问题的回答。]
[In fact I wrote that before I saw your "in C++ mode" remark. I
suspect you don''t need C''s answer to this question.]



C ++模式仅用于编译在msvc中,因为我正在使用一个/或
的C99特性(代码块中的变量声明),msvc C编译器不支持
。在linux中,我使用gcc在C99模式下编译


The C++ mode is only used for compiling in msvc, because I''m using a
number of C99 features (variable declarations anywere in a code block),
that are not supported in the msvc C compiler. In linux, I am compiling
in C99 mode with gcc.


>我如何制作这项工作?我可以移动
mydevice_backend的定义。变量到源文件的顶部并转发
声明结构中的每个函数,但是能够转发声明变量本身会更加优雅。
>How can I make this work? I could move the definition of the
"mydevice_backend" variable to the top of the source file and forward
declare each function inside the structure, but being able to forward
declare the variable itself would be much more elegant.



您可以在C中,但可能不在C ++中。 C ++人可以告诉你。


You can in C, but maybe not in C++. The C++ people can tell you.


这篇关于正向声明静态变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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