初始化包含opaque类型的复合类型 [英] Initializing compound type containing opaque type

查看:75
本文介绍了初始化包含opaque类型的复合类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下伪代码:


#include< opaque.h>


struct foo {

int a;

opaque_t op;

int b;

};


struct foo blah = {17,/ * ??? * /,23};


这里我们假设'opaque_t''在< opaque.has中定义了某种类型

我们不知道,或者我们不能依赖。特别是,它可能是标量或复合类型的b $ b。我们的目标是以blah.a == 17和blah.b == 23的方式初始化`blah''。我们不关心`blah.op'的

值。


在我看来,没有办法做到这一点标准C.这是否正确,或者我错过了什么?


一种解决方法是将`struct foo'的成员重新排列为


struct foo2 {

int a;

int b;

opaque_t op;

};


struct foo2 blah2 = {17,23};


我相信这是合法的,但我可能是错误。我的编译器警告

关于缺少初始值设定项,但接受代码。


如果已知'opaque_t''是复合类型,我们可以写


struct foo blah3 = {17,{},23};


再次引发缺少的初始化器警告但被接受。

再次,我很好奇它是否真的合法。


我在几周前阅读这篇文章后想到了这个问题,

异常处理崩溃或退出作者:Fabiano Sidler,

< 48 ********** @ news.bluewin.ch> ;,其中海报想要一个结构

with a jmp_buf作为一个成员。他使用{0},

初始化该成员,这肯定是不可移植的。但是我想知道是否有一种可靠的便携式方式来做同样的事情。


如果没有,它似乎对于<的作者有用; opaque.h>

提供一个适合作为opaque_t初始化程序的宏。

Eg < opaque.hmight包含


typedef opaque_t struct {

int x,

double d;

};


#define OPAQUE_INITIALIZER {0,0.0}


所以可以写一个


struct foo blah = {17,OPAQUE_INITIALIZER,23};


特别是,对于图书馆作者而言,这可能是一个有用的扩展,以便为b
提供不透明的库类型(例如jmp_buf,FILE等)。


有什么想法吗?

解决方案

10月2,上午12:05,Nate Eldredge< n ... @ vulcan.lanwrote:


考虑以下伪代码:


#include< opaque.h>


struct foo {

int a;

opaque_t op;

int b;


};


struct foo blah = {17,/ * ??? * /,23};


这里我们假设'opaque_t''在< opaque.has中定义了某种类型

我们不知道,或者我们不能依赖。特别是,它可能是标量或复合类型的b $ b。我们的目标是以blah.a == 17和blah.b == 23的方式初始化`blah''。我们不关心`blah.op'的

值。


在我看来,没有办法做到这一点标准C.这是否正确,或者我错过了什么?


一种解决方法是将`struct foo'的成员重新排列为


struct foo2 {

int a;

int b;

opaque_t op;


};


struct foo2 blah2 = {17,23};


我相信这是合法的,但我可能是错的。我的编译器警告

关于缺少初始化程序,但接受代码。



是的,这是合法的。

(注意:在POSIX中它不会; * _t是保留标识符)


如果知道`opaque_t''是复合类型,我们可以写


struct foo blah3 = {17 ,{},​​23};


再次引发缺少的初始化器警告但被接受。

再次,我很好奇它是否真的合法。



也合法。


我在几周前阅读这篇文章后想到了这个问题,

异常处理崩溃或退出作者:Fabiano Sidler,

< 48c4e24d


... @ news.bluewin.ch> ;,其中海报想要一个结构

,jmp_buf为一个成员。他使用{0},

初始化该成员,这肯定是不可移植的。但我想知道是否有一种可靠的方式可以做同样的事情。



是的,jmp_buf foo = {0};


虽然这会将所有成员初始化为0,0.0或NULL取决于

类型,递归地应用于任何聚合


如果不是,它似乎对<的作者有用。 opaque.h>

提供适合作为opaque_t初始化程序的宏。



嗯,这是合法的,所以它没用。


例如< opaque.hmight包含



< snip>


Nate Eldredge写道:
< blockquote class =post_quotes>
考虑以下伪代码:


#include< opaque.h>


struct foo {

int a;

opaque_t op;

int b;

};


struct foo blah = {17,/ * ??? * /,23};


这里我们假设'opaque_t''在< opaque.has中定义了某种类型

我们不知道,或者我们不能依赖。特别是,它可能是标量或复合类型的b $ b。我们的目标是以blah.a == 17和blah.b == 23的方式初始化`blah''。我们不关心`blah.op'的

值。



在C99中你可以使用复合文字:


struct foo blah =(struct foo){ .a = 17,.b = 23};


(仔细检查我的语法;我正在急忙打字。)


在C90中你可以将未知成员初始化为零/

合适的类型:


struct foo blah = {17,{0} ,23};


有些编译器可能会因初始化程序太少而发出警告,但初始化有效则为
;如果opaque_t是复合的,则其子元素b $ b元素被初始化为适当的零。警告可能会令人讨厌,但他们没有实际的伤害。


-
Er ********* @ sun.com


Consider the following pseudo-code:

#include <opaque.h>

struct foo {
int a;
opaque_t op;
int b;
};

struct foo blah = { 17, /* ??? */ , 23 };

Here we suppose that `opaque_t'' is defined in <opaque.has some type
not known to us, or which we cannot rely on. In particular, it may be
a scalar or compound type. The goal is to initialize `blah'' in such a
way that `blah.a == 17'' and `blah.b == 23''. We don''t care about the
value of `blah.op''.

It seems to me that there is no way to do this in standard C. Is this
correct, or am I missing something?

A workaround would be to rearrange the members of `struct foo'' as

struct foo2 {
int a;
int b;
opaque_t op;
};

struct foo2 blah2 = { 17, 23 };

I believe this is legal, but I could be wrong. My compiler warns
about a missing initializer, but accepts the code.

If `opaque_t'' is known to be a compound type, we could write

struct foo blah3 = { 17, { }, 23 };

which again provokes a missing initializer warning but is accepted.
Again I am curious whether it is actually legal.

I thought of this issue after reading a post here a couple weeks ago,
"Exception handling crashes or exits" by Fabiano Sidler,
<48**********@news.bluewin.ch>, in which the poster wants a struct
with a jmp_buf as one member. He initializes that member with { 0 },
which is certainly non-portable. But I wondered if there is a
portable way to do the same thing.

If not, it seems like it might be useful for the authors of <opaque.h>
to provide a macro which is suitable as an initializer for opaque_t.
E.g. <opaque.hmight contain

typedef opaque_t struct {
int x,
double d;
};

#define OPAQUE_INITIALIZER { 0, 0.0 }

so that one could write

struct foo blah = { 17, OPAQUE_INITIALIZER, 23 };

In particular, this could be a useful extension for library authors to
provide for opaque library types (e.g. jmp_buf, FILE, etc).

Any thoughts?

解决方案

On Oct 2, 12:05 am, Nate Eldredge <n...@vulcan.lanwrote:

Consider the following pseudo-code:

#include <opaque.h>

struct foo {
int a;
opaque_t op;
int b;

};

struct foo blah = { 17, /* ??? */ , 23 };

Here we suppose that `opaque_t'' is defined in <opaque.has some type
not known to us, or which we cannot rely on. In particular, it may be
a scalar or compound type. The goal is to initialize `blah'' in such a
way that `blah.a == 17'' and `blah.b == 23''. We don''t care about the
value of `blah.op''.

It seems to me that there is no way to do this in standard C. Is this
correct, or am I missing something?

A workaround would be to rearrange the members of `struct foo'' as

struct foo2 {
int a;
int b;
opaque_t op;

};

struct foo2 blah2 = { 17, 23 };

I believe this is legal, but I could be wrong. My compiler warns
about a missing initializer, but accepts the code.

Yes, it''s legal.
(note: In POSIX it wouldn''t be; *_t are reserved identifiers)

If `opaque_t'' is known to be a compound type, we could write

struct foo blah3 = { 17, { }, 23 };

which again provokes a missing initializer warning but is accepted.
Again I am curious whether it is actually legal.

Also legal.

I thought of this issue after reading a post here a couple weeks ago,
"Exception handling crashes or exits" by Fabiano Sidler,
<48c4e24d


...@news.bluewin.ch>, in which the poster wants a struct
with a jmp_buf as one member. He initializes that member with { 0 },
which is certainly non-portable. But I wondered if there is a
portable way to do the same thing.

Yes, jmp_buf foo = {0};

Though that''d initialize all members to 0, 0.0 or NULL depending on
type, recursively applied for any aggregate

If not, it seems like it might be useful for the authors of <opaque.h>
to provide a macro which is suitable as an initializer for opaque_t.

Well, it is legal, so it''s not useful.

E.g. <opaque.hmight contain

<snip>


Nate Eldredge wrote:

Consider the following pseudo-code:

#include <opaque.h>

struct foo {
int a;
opaque_t op;
int b;
};

struct foo blah = { 17, /* ??? */ , 23 };

Here we suppose that `opaque_t'' is defined in <opaque.has some type
not known to us, or which we cannot rely on. In particular, it may be
a scalar or compound type. The goal is to initialize `blah'' in such a
way that `blah.a == 17'' and `blah.b == 23''. We don''t care about the
value of `blah.op''.

In C99 you could use a "compound literal:"

struct foo blah = (struct foo){.a = 17, .b = 23};

(Double-check my syntax; I''m typing this hurriedly.)

In C90 you could initialize the unknown member to "zero of
the appropriate type:"

struct foo blah = { 17, { 0 }, 23 };

Some compilers may emit warnings for too few initializers, but
the initialization is valid; if opaque_t is compound, its sub-
elements are initialized to appropriate zeroes. The warnings may
be a nuisance, but they do no actual harm.

--
Er*********@sun.com


这篇关于初始化包含opaque类型的复合类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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