使用联合来获得不同的表示 [英] Using a union to get different representation

查看:83
本文介绍了使用联合来获得不同的表示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道在使用该成员初始化时,使用

联盟的成员是否被认为是未定义的行为。例如:


typedef unsigned long hval_t;


hval_t hval_init(无效)

{

union hval_init_u {double dbl; hval_t hval; };

union hval_init_u phi = {(sqrt(5)+ 1)/ 2}; / *黄金比例* /


返回phi.hval;

}


我在这里看到一个帖子很久以前使用

char *来索引一个double值并将字节复制到unsigned long,

是合理的,但似乎很多这样做更快更容易。


我想用它作为哈希函数的默认位模式。

它不会必须是便携式的。它只需要有点随机,并且这似乎是一种合理的方式。


-Clint

I was wondering if it''s considered undefined behavior to use a member of a
union when it wasn''t initialized with that member. Example:

typedef unsigned long hval_t;

hval_t hval_init(void)
{
union hval_init_u { double dbl; hval_t hval; };
union hval_init_u phi = { (sqrt(5) + 1) / 2 }; /* golden ratio */

return phi.hval;
}

I saw on a thread here quite some time ago that it''s reasonable to use a
char * to index into a double value and copy the bytes to an unsigned long,
but it seems much quicker and easier to do it this way.

I was wanting to use this as my default bit pattern for a hash function.
It doesn''t have to be portable. It just needs to be somewhat random, and
this seemed like a reasonable way.

-Clint

推荐答案

>我想知道如果使用
> I was wondering if it''s considered undefined behavior to use a member of a
union的成员,当它没有被该成员初始化时,它是否被认为是未定义的行为。示例:

typedef unsigned long hval_t;

hval_t hval_init(void)
{union / hval_init_u {double dbl; hval_t hval; };
union hval_init_u phi = {(sqrt(5)+ 1)/ 2}; / *黄金比例* /

返回phi.hval;
}


我似乎无法在C标准中找到它但是这里是来自C ++

标准的文本:在一个联盟中,任何时候最多只有一个数据成员可以在

处活动,也就是说,最多一个数据成员可以随时存储在一个工会中。 [注意:为了简化联合的使用,我们在

命令中做了一个特殊的保证:如果POD-union包含几个共享一个共同初始序列的
POD结构( 9.2),如果此POD-union类型的

对象包含其中一个POD结构,则允许检查任何POD的公共初始序列的
-struct

成员;见9.2。 ]


C99标准与初始常见的

序列措辞几乎完全相同,但不是活跃成员的措辞,这很奇怪

,因为它与它有关。我正在把C ++的措辞作为正确的

一个,所以我会说上面的内容是未定义的,但是由于

人们滥用它而在实践中工作。 br />
我在很久以前的一个帖子中看到,使用
char *索引为double值并将字节复制到unsigned long是合理的,
但这样做似乎更快更容易。
union when it wasn''t initialized with that member. Example:

typedef unsigned long hval_t;

hval_t hval_init(void)
{
union hval_init_u { double dbl; hval_t hval; };
union hval_init_u phi = { (sqrt(5) + 1) / 2 }; /* golden ratio */

return phi.hval;
}
I can''t seem to find it in the C standard but here is text from the C++
standard: "In a union, at most one of the data members can be active at
any time, that is, the value of at most one of the data members can be
stored in a union at any time. [Note: one special guarantee is made in
order to simplify the use of unions: If a POD-union contains several
POD-structs that share a common initial sequence (9.2), and if an
object of this POD-union type contains one of the POD-structs, it is
permitted to inspect the common initial sequence of any of POD-struct
members; see 9.2. ]"

The C99 standard has almost exactly the same the initial common
sequence wording but not the active member wording, which is weird
because it is related to it. I''m taking the C++ wording as the correct
one, so I would say the above is undefined but works in practice due to
people abusing it so much.
I saw on a thread here quite some time ago that it''s reasonable to use a
char * to index into a double value and copy the bytes to an unsigned long,
but it seems much quicker and easier to do it this way.




不要害怕使用memcpy。大多数编译器将它实现为

内在函数,因此它应该生成最有效的代码(除了一个实际上可以保证工作的
)。



Don''t be afraid to use memcpy. Most compilers implement it as an
intrinsic so it should generate the most efficient code (except one
that actually is guaranteed to work).


2005-07-07,Me< an ***************** @ yahoo.com>写道:
On 2005-07-07, Me <an*****************@yahoo.com> wrote:
我似乎无法在C标准中找到它,但这里是来自C ++
标准的文本:在一个联盟中,最多只有一个数据成员可以在任何时候都要活跃,也就是说,最多一个数据成员的价值可以随时存储在一个联盟中。 [注意:为了简化联合的使用,有一个特殊的保证:如果POD-union包含几个共享一个共同初始序列的POD结构(9.2),并且一个对象<这个POD-union类型包含一个POD结构,允许检查任何POD结构成员的公共初始序列;见
9.2。 ]

C99标准几乎与最初的常用序列
措辞完全相同,但不是活跃的成员措辞,这很奇怪,因为它与之相关。我正在把C ++的措辞作为正确的措辞,所以我会说上面的内容是未定义的但是由于人们滥用它而在实践中工作很多。

Don不要害怕使用memcpy。大多数编译器都将它作为内在函数实现,因此它应该生成最有效的代码(除了一个确实可以保证工作的代码)。
I can''t seem to find it in the C standard but here is text from the C++
standard: "In a union, at most one of the data members can be active at
any time, that is, the value of at most one of the data members can be
stored in a union at any time. [Note: one special guarantee is made in
order to simplify the use of unions: If a POD-union contains several
POD-structs that share a common initial sequence (9.2), and if an object
of this POD-union type contains one of the POD-structs, it is permitted
to inspect the common initial sequence of any of POD-struct members; see
9.2. ]"

The C99 standard has almost exactly the same the initial common sequence
wording but not the active member wording, which is weird because it is
related to it. I''m taking the C++ wording as the correct one, so I would
say the above is undefined but works in practice due to people abusing it
so much.

Don''t be afraid to use memcpy. Most compilers implement it as an
intrinsic so it should generate the most efficient code (except one
that actually is guaranteed to work).




我曾经考虑过这个问题,但是因为实现边界很短(呃)

直接检查for循环中的unsigned long和double,我只需要复制
它手动。好吧,所以我懒得写一个MIN宏:)

这对联盟来说非常方便,因为它可以为我处理任何长度

的差异。 br />

我在想,也许从不同的成员写作和阅读

会导致读取值的陷阱表示?肯定

不会导致对齐问题,因为工会保证这不应该是
a问题。


谢谢调查这个。


-Clint



I had considered that, but since it was short(er) to implement the bounds
checking for both the unsigned long and double in the for loop directly, I
just copied it manually. Ok, so I was too lazy to write a MIN macro :)
It''s just very convenient with the union since it handles any length
differences for me.

I was thinking that perhaps writing and reading from different members
could cause a trap representation for the read value? It certainly
couldn''t cause alignment problems as the union guarantees this shouldn''t be
a problem.

Thanks for looking into this.

-Clint


>我在想,也许从不同成员写作和阅读
> I was thinking that perhaps writing and reading from different members
可能会导致读取值的陷阱表示?它肯定不会导致对齐问题,因为工会保证这不应该是一个问题。
could cause a trap representation for the read value? It certainly
couldn''t cause alignment problems as the union guarantees this shouldn''t be
a problem.




没有价值组合bit被允许是一个陷阱表示

一个无符号整数但是填充位的组合是(并且唯一的保证没有填充位的
事物是unsigned char)。在你原来的

原帖中,你说它不必是可移植的,我认为你已经知道你的b / b了解你的实现中双打和未签名多头的格式。 />



No combination of value bits is allowed to be a trap representation on
an unsigned integer but combinations of padding bits are (and the only
thing guaranteed not to have padding bits is unsigned char). In your
original post, you said it didn''t have to be portable and I assumed you
knew the format of doubles and unsigned longs on your implementation.


这篇关于使用联合来获得不同的表示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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