工会,存储,ABI [英] Unions, storage, ABI's

查看:63
本文介绍了工会,存储,ABI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨!


有谁知道标准中关于工会存储在C中的方式是什么?b $ b?我的意思是:


假设你有一个带有double和char字段的联合:


union MyUnion_t

{

double double;

char Char;

};


MyUnion_t aUnion;


它是否标准化了分配存储的哪个字节

Char字段将使用?


和一个相关的问题:如果你将二进制形式的工会转储到一个文件,

然后从另一个平台上的文件或者一个

程序重新加载它们由不同的编译器编译,你保证得到你存储的内容吗? (我想不是,但我不确定)


还有一点:如果你在不同的ABI中使用相同的联合,

这会没有问题吗?例如:如果你从一个特定的编译器编译的库得到一个指向

这样的联合的指针,然后

在另一个使用不同编译器编译的模块中使用它,将会是按照预期的那样工作吗?


comp.std.c小组的某个人发现了这个:

C99 6.7 .2.1p14说:

联盟的大小足以容纳其中最大的成员。最多一个成员的值可以随时存储在一个union对象中。指向联合对象的指针(适当地转换)指向其每个成员(或者如果成员是一个位 -
字段,然后指向它所在的单位),反之亦然。 / blockquote>


这似乎不能保证多少呢?

我希望使用(* ptr).Char或(* ptr ).Double,无需投出任何东西。看起来没有更多详细说明是否这是

假设

在不同的ABI上工作:


MyUnion_t theUnion;

somelib-> getUnion(& theUnion);


这是我自己的程序,而somelib是一个函数表到

库可能是由另一个编译器编译的。

库是否会返回一个与我自己的

程序相同的二进制布局的联合?


Koen

解决方案

Koen写道:


嗨!

有谁知道标准中关于工会存储在C中的方式的含义?我的意思是:

让我们说你有一个双人和一个char字段的联盟:

union MyUnion_t

双倍;
char Char;
};

MyUnion_t aUnion;

是否标准化了分配存储的哪个字节
Char字段会用吗?


& aUnion.Double和& aUnion.Char是平等的。

和一个相关的问题:如果你将二进制形式的联盟转储到文件中,
然后从不同平台上的文件重新加载它们,或者用不同编译器编译的程序重新加载它们,你能保证得到你存储的内容吗? (我想不是,但我不确定)




你是对的;你不是。


" Koen" < no@ssppaamm.com>写道:

有谁知道标准中关于工会存储在C中的方式的内容?我的意思是:

让我们说你有一个双人和一个char字段的联盟:

union MyUnion_t

双倍;
char Char;
};

MyUnion_t aUnion;

是否标准化了分配存储的哪个字节
Char字段会用吗?
[...]

我希望使用(* ptr).Char或(* ptr).Double,无需投出任何东西。看起来没有更多详细说明这是否应该在不同的ABI中工作:

MyUnion_t theUnion;
somelib-> getUnion( & theUnion);

这是在我自己的程序中,somelib是一个函数表,可能是由另一个编译器编译的库。
libary会返回一个联合吗?使用与我自己的
程序相同的二进制布局?




当然你可以使用(* ptr).Char或(* ptr).Double引用

相应的成员(或者,更通俗地说,ptr-> Char或

ptr-> Double)。转换既不必要也不有用,因为

表达式已经是正确的类型。如果联盟包含

有效数据,您可以访问它;如果它没有,那么施放就没有帮助。


不能保证不同编译器生成的代码将使用相同的b
工会,结构或其他任何东西的布局。但是如果

编译器在同一个系统上,并且你可以将它们生成的代码链接到一个可执行文件中,那么编译器供应商几乎就可以了。 $ b肯定已经做了一些努力使他们的布局兼容。


-

Keith Thompson(The_Other_Keith) ks *** @ mib.org < http://www.ghoti.net/~kst>

圣地亚哥超级计算机中心< *> ; < http://users.sdsc.edu/~kst>

我们必须做点什么。这是事情。因此,我们必须这样做。


Koen< no@ssppaamm.com>写道:

有谁知道标准中关于工会存储在C中的方式是什么?我的意思是:
假设你有一个带有double和char字段的联合:
union MyUnion_t
{
double double;
char Char ;
};
MyUnion_t aUnion;


你需要


联盟MyUnion_t aUnion;


因为MyUnion_T不是典型的但只是一个标签......

它是否标准化了某个字段将分配的存储空间将使用的字段?


您之后引用的内容,即

...指向联合对象的指针,适当<转换后,指向其每个成员(或者如果成员是一个位 -
字段,然后指向它所在的单位),反之亦然。




告诉''Double''和''Char''成员将在工会的第一个地址。即


& AUninon.Double ==(double *)& AUnion

& AUninon.Char ==(char *)& AUnion


这就是那个句子的含义,即你可以在

之后使用& AUnion作为指向''Double'的指针'或者''Char''

成员(如果这样做很有意义则是一个不同的问题)。

和一个相关的问题:如果你以二进制方式转储联盟表单到文件,
然后从不同平台上的文件重新加载它们,或者用不同的编译器编译的程序,你保证得到你存储的内容吗? (我想不是,但我不确定)


在不同的平台上,这绝对不能保证

工作 - 浮点格式可以完全不同(已经

sizeof(double)可能不同)并且char中的位数可能不同(即CHAR_BIT的值来自限制)。 h>)以及

编码。即使使用不同的编译器编译,你也可以理论上如果使用不同数量的位来存储浮点数,理论上会遇到麻烦,但我猜这是一个极端 -

不太可能出现这种情况。

还有一点:如果你在不同的ABI中使用相同的联盟,
那会没有问题吗?例如:如果你从一个特定编译器编译的库中获得指向这样一个联合的指针,然后在另一个使用不同编译器编译的模块中使用它,那将会是一个联盟。按预期工作?


作为一项规则,我希望它可以工作,因为很多东西可能会破坏

如果不同的编译器使用不同的字符或双精度(你可能

在这种情况下根本无法链接,因为库需要使用不同的libc来获取
。但我不认为

的承诺是它始终有效的标准。

comp.std.c组的某个人发现了这个:< blockquote class =post_quotes>任何时候的联合对象。指向联合对象的指针(适当地转换)指向其每个成员(或者如果成员是一个位 -
字段,然后指向它所在的单位),反之亦然。 / blockquote>
这似乎不能保证多少呢?
我希望使用(* ptr).Char或(* ptr).Double而不必投任
任何东西。看起来没有详细说明这是否应该适用于不同的ABI:


不,你不需要演员。这句话只是说你可以在合适的转换后使用联盟的

地址作为指向其成员的每个

的指针,这保证每个成员在一开始就放置

的结构。但是使用''ptr-> Char''或

''ptr-> Double''没有演员阵容没有错 - 通过指定你已经成员

告诉编译器这是什么类型。所以''ptr-> Char''是一个字母和

''ptr-> Double''双倍没有任何演员。

MyUnion_t theUnion;
somelib-> getUnion(& theUnion);
这是在我自己的程序中,somelib是一个函数表,可能是由另一个编译器编译的库。
libary会返回一个与我自己的二进制布局相同的联合吗?程序会做什么?




正如我上面写的那样,它很可能会起作用,但我没有看到它有

a保证。但如果它不起作用,我会期望在

连接阶段的事情会失败,因为这样的差异很可能导致很多地方出现麻烦。 。

问候,Jens

-

\ Jens Thoms Toerring ___ Je *********** @ physik.fu-berlin.de

\ __________________________ http://www.toerring.de

Hi!

Does anyone know what the standard says about the way unions are
stored in C? I mean the following:

Let''s say you have a union with a double and a char field:

union MyUnion_t
{
double Double;
char Char;
};

MyUnion_t aUnion;

Is it standardized somehow which byte of the allocated storage the
Char field will use?

And a related question: if you dump unions in binary form to a file,
and then reload them from the file on a different platform, or with a
program compiled by a different compiler, are you guaranteed to get
back what you stored? (I think not, but I''m not sure)

And another point: if you use the same union across different ABI''s,
will that work without problems? For example: if you get a pointer to
such a union from a library compiled by a specific compiler, and then
use it in another module compiled with a different compiler, will
aUnion.Char work as expected?

Someone on the comp.std.c group found this:

C99 6.7.2.1p14 says:

The size of a union is sufficient to contain the largest of its
members. The value of at most one of the members can be stored in
a union object at any time. A pointer to a union object, suitably
converted, points to each of its members (or if a member is a bit-
field, then to the unit in which it resides), and vice versa.



That doesn''t seem to guarantee much does it?
I was hoping to use (*ptr).Char or (*ptr).Double without having to cast
anything. Looks like no more details are specified about whether this is
supposed
to work across different ABI''s:

MyUnion_t theUnion;
somelib->getUnion(&theUnion);

where this is in my own program, and somelib is a function table into a
library possibly compiled by another compiler.
Will the libary return a union with the same binary layout as my own
program would do?

Koen

解决方案

Koen wrote:


Hi!

Does anyone know what the standard says about the way unions are
stored in C? I mean the following:

Let''s say you have a union with a double and a char field:

union MyUnion_t
{
double Double;
char Char;
};

MyUnion_t aUnion;

Is it standardized somehow which byte of the allocated storage the
Char field will use?
&aUnion.Double and &aUnion.Char are equal.

And a related question: if you dump unions in binary form to a file,
and then reload them from the file on a different platform, or with a
program compiled by a different compiler, are you guaranteed to get
back what you stored? (I think not, but I''m not sure)



You''re right; you''re not.


"Koen" <no@ssppaamm.com> writes:

Does anyone know what the standard says about the way unions are
stored in C? I mean the following:

Let''s say you have a union with a double and a char field:

union MyUnion_t
{
double Double;
char Char;
};

MyUnion_t aUnion;

Is it standardized somehow which byte of the allocated storage the
Char field will use? [...]
I was hoping to use (*ptr).Char or (*ptr).Double without having to cast
anything. Looks like no more details are specified about whether this is
supposed
to work across different ABI''s:

MyUnion_t theUnion;
somelib->getUnion(&theUnion);

where this is in my own program, and somelib is a function table into a
library possibly compiled by another compiler.
Will the libary return a union with the same binary layout as my own
program would do?



Of course you can use (*ptr).Char or (*ptr).Double to refer to the
corresponding members (or, more idiomatically, ptr->Char or
ptr->Double). Casting would be neither necessary nor useful, since
the expression is already of the correct type. If theUnion contains
valid data, you can access it; if it doesn''t, casting won''t help.

There''s no guarantee that code generated by different compilers will
use the same layout for unions, structs, or anything else. But if the
compilers are on the same system, and you can link code generated by
them into a single executable, the compiler vendors will almost
certainly have made some effort to make their layouts compatible.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.


Koen <no@ssppaamm.com> wrote:

Does anyone know what the standard says about the way unions are
stored in C? I mean the following: Let''s say you have a union with a double and a char field: union MyUnion_t
{
double Double;
char Char;
}; MyUnion_t aUnion;
You need

union MyUnion_t aUnion;

here since MyUnion_T isn''t typdefed but just a tag...
Is it standardized somehow which byte of the allocated storage the
Char field will use?
What you cited later, i.e.

... A pointer to a union object, suitably
converted, points to each of its members (or if a member is a bit-
field, then to the unit in which it resides), and vice versa.



tells that both the ''Double'' and ''Char'' members will be at the very
first address of the union. I.e.

&AUninon.Double == (double *) &AUnion
&AUninon.Char == (char * ) &AUnion

That''s what is meant by that sentence, i.e. you can use &AUnion after
suitable casting either as a pointer to the ''Double'' or to the ''Char''
member (if doing so makes much sense is a different question).
And a related question: if you dump unions in binary form to a file,
and then reload them from the file on a different platform, or with a
program compiled by a different compiler, are you guaranteed to get
back what you stored? (I think not, but I''m not sure)
On a different platform this will definitely not be guaranteed to
work - the floating point format can be completely different (already
sizeof(double) may differ) and also the number of bits in a char could
be different (i.e. the value of CHAR_BIT from limits.h>) as well as
the encoding. Even when compiled with a different compiler you could
theoretically get in trouble if the use different numbers of bits to
store floating point numbers, but I would guess that this is an extre-
mely unlikely case.
And another point: if you use the same union across different ABI''s,
will that work without problems? For example: if you get a pointer to
such a union from a library compiled by a specific compiler, and then
use it in another module compiled with a different compiler, will
aUnion.Char work as expected?
As a rule I would expect it to work since a lot of things might break
if different compilers use different chars or doubles (you probably
wouldn''t be able to link at all in that case since the libraries would
need t use a different libc). But I don''t think there''s a promise in
the standard that it will always work.
Someone on the comp.std.c group found this:

a union object at any time. A pointer to a union object, suitably
converted, points to each of its members (or if a member is a bit-
field, then to the unit in which it resides), and vice versa.

That doesn''t seem to guarantee much does it?
I was hoping to use (*ptr).Char or (*ptr).Double without having to cast
anything. Looks like no more details are specified about whether this is
supposed to work across different ABI''s:
No, you don''t need a cast. The sentence just says that you can use the
address of the union after suitable conversion as a pointer to each
of its members, which guarantees that each member lays at the start
of the structure. But there''s nothing wrong with using ''ptr->Char'' or
''ptr->Double'' without the cast - by specifying the member you already
tell the compiler which type is meant. So ''ptr->Char'' is a char and
''ptr->Double'' a double without any casts.
MyUnion_t theUnion;
somelib->getUnion(&theUnion); where this is in my own program, and somelib is a function table into a
library possibly compiled by another compiler.
Will the libary return a union with the same binary layout as my own
program would do?



As I wrote above, it''s very likely to work, but I don''t see that there''s
a guarantee. But if it doesn''t work I would expect things to fail at the
linking stage since such differences would rather likely lead to a lot of
trouble all over the place.
Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de


这篇关于工会,存储,ABI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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