真实联盟 [英] Real Life Unions

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

问题描述



最近一个向工会寻求帮助的帖子让我想起了这个我只使用了几次的C语言的
组件,

和那些几乎完全出于个人心血来潮的人 - 工会的缘故

的工会只是因为我想看到一个在行动。


当然:它可以节省几个字节的存储空间,当你的b $ b有一些可以是鸡或公鸡的东西,但不是两个,并且

你''我总是会知道它是什么。


但是我不觉得我曾经遇到过一个问题,我在这里打了个$
并且说,工会将是完美的!这个

似乎总是设计错误,将不同类型的卡塞到

单个符号中,或者至少是一个要求麻烦的设计。


也就是说,我不会为嵌入式设备编写设备驱动程序,内核或软件。空间通常不是关注的问题

me:清晰度,可维护性和无bug几乎总是我的#1

目标。


但是我很好奇,在c程序员的社区中,是否工会

在工程师的工具包中有一个荣誉位置,或者他们是否更像是b $ b更像是一个旧的锥子在盒子的黑暗角落里踢。感觉

免费提供联盟历史上伟大时刻的指导性示例!

解决方案

bluejack写道:


最近一篇向工会求助的帖子让我想起了这个我只使用了几次的C语言的
组件,

和那些几乎完全出于个人心血来潮的人 - 工会的缘故

的工会只是因为我想看到一个在行动。


授予:它可以节省几个字节的存储空间

有可能是鸡或公鸡的东西,但不是两者都有,并且

你总是会知道它是什么。


但是我不觉得我曾经遇到过一个问题我被击打了

自己在头上说:工会对此很完美!这个

似乎总是设计错误,将不同类型的卡塞到

单个符号中,或者至少是一个要求麻烦的设计。


也就是说,我不会为嵌入式设备编写设备驱动程序,内核或软件。空间通常不是关注的问题

me:清晰度,可维护性和无bug几乎总是我的#1

目标。


但是我很好奇,在c程序员的社区中,是否工会

在工程师的工具包中有一个荣誉位置,或者他们是否更像是b $ b更像是一个旧的锥子在盒子的黑暗角落里踢。感受

免费提供联盟历史上伟大时刻的指导性示例!



恕我直言的工会比黑暗的角落更接近

光线充足的顶部抽屉,但他们是一个工具如果有人借用它们并忘记将它们退回到你的

工具箱中,我们将错过




节省空间已经成为一个肮脏的词,沿着b效率和效率。但这很大程度上是针对过剩的反弹,反对在Hello,world!中再节省一个字节

或一个多微秒的仪式性驱动器。程序。那里有
仍然是储蓄很重要的情况。


其中,节省空间的情况经常比b
更合理)节省时间的情况。你已经提到在穷人的O-O中使用工会了吗?多态的情况,

,很容易看出,在一个富有的对象层次结构中,

很多,而不是亲近的关系空间

储蓄可能是巨大的。此外,在这种情况下,空间节省

可以轻松等同于节省时间:与现代CPU相比,

内存是狗慢和变慢(我们奖励我们的记忆

制造商的密度和成本,而不是速度)。如果你将
打包成四个Thing实例进入一个缓存行,而不仅仅是两个b

,你有机会将缓存未命中率降低一半

并使您的计划快30-60%。那种效率

不在脏词中。部门;它就像是在一个循环中剃掉一微秒的愚蠢运动,这将是b
总共运行三次。


你提到了设备驱动程序。对于多态编程来说,有一个'成熟的'
的领域:你将拥有一个通用框架

,它在设备盲和设备感知部分之间架起桥梁

的系统,也许在设备感知层你会有进一步的抽象(我们在SCSI驱动程序中,但我们是不是/>
与磁盘或磁带通信?)。构建

这样的框架的一种便捷方法是让最低级别的部分构建结构

,包含其特定设备所需的所有信息,然后

将它们移交给不知道

细节的更高层。这是行动,密友和工会中的多态性

是实现它的好方法。不是唯一的方法,而是一个好方法。


所以,总是寻找工会标签。


-

Eric Sosman
es*****@acm-dot-org.inva 盖子


bluejack< bl ****** @ gmail.comwrote:


> Feel免费提供联盟历史上伟大时刻的指导性例子!



一些互联网套接字实现过去常常使用像这样的联盟

(有些可能仍然可以)用于IPv4地址:


struct in_addr {

union {

struct {u_charwers1,shield2,shield3,shield4; } S_un_b;

struct {u_short s_w1,s_w2; } S_un_w;

u_long S_addr;

} S_un;

}

#define s_addr S_un.S_addr


通过这种方式,你可以将互联网地址看作4个8位块,2个
16位块或1个32位块(使用定义)以
" foo.s_addr"来访问它。)

原来大多数人使用32位表示法,在Linux下,

无论如何,工会早已不复存在:


typedef uint32_t in_addr_t;

struct in_addr

{

in_addr_t s_addr;

};


但是再看一下代码,联盟再次用于

IPv6内容:


/ * IPv6地址* /

struct in6_addr

{

union

{

uint8_t u6_addr8 [16];

uint16_t u6_addr16 [8];

uint32_t u6_addr32 [4];

} in6_u;

#define s6_addr in6_u.u6_addr8

#define s6_addr16 in6_u.u6_ addr16

#define s6_addr32 in6_u.u6_addr32

};


-Beej


bluejack写道:


最近一个向工会求助的帖子让我想起了这个

组件C语言,我只使用了几次,

和那些几乎完全出于个人的心血来潮 - 为了工会的缘故,工会只需因为我想看到一个在行动。



< snip>


>

但我很好奇,在c程序员社区中,是否工会

有一个在工程师的工具包中获得荣誉的地方,或者他们是否更像是一个旧的锥子在盒子的黑暗角落里踢。感觉

免费提供联盟历史上伟大时刻的指导性示例!



使用(大)联合的一大堆代码是标准Unix

窗口环境,Xlib。所有X事件在一个联合中表示为结构

,其中第一个结构成员是事件ID。


-

Ian Collins。



A recent post asking for help with unions reminded me of this
component of the C language that I have only used a couple of times,
and those almost entirely out of personal whim -- Unions for the sake
of Unions simply because I wanted to see one in action.

Granted: it makes it possible to save a few bytes of storage when you
have something that can be a chicken or a rooster, but not both, and
you''re always going to know which it is.

But I don''t think I''ve ever encountered a problem where I smacked
myself in the head and said, "A union would be perfect for this!" It
always seems like a design error to go jamming different types into a
single symbol, or at least a design that''s asking for trouble.

That said, I don''t write device drivers, kernels, or software for
embedded devices. Space is not usually the constraint that concerns
me: clarity, maintainability, and buglessness are almost always my #1
goals.

But I was curious, in the community of c programmers, whether Unions
had an honored place in the engineer''s toolkit, or whether they were
more like an old awl kicking around the dark corners of the box. Feel
free to provide instructive examples of great moments in Union history!

解决方案

bluejack wrote:

A recent post asking for help with unions reminded me of this
component of the C language that I have only used a couple of times,
and those almost entirely out of personal whim -- Unions for the sake
of Unions simply because I wanted to see one in action.

Granted: it makes it possible to save a few bytes of storage when you
have something that can be a chicken or a rooster, but not both, and
you''re always going to know which it is.

But I don''t think I''ve ever encountered a problem where I smacked
myself in the head and said, "A union would be perfect for this!" It
always seems like a design error to go jamming different types into a
single symbol, or at least a design that''s asking for trouble.

That said, I don''t write device drivers, kernels, or software for
embedded devices. Space is not usually the constraint that concerns
me: clarity, maintainability, and buglessness are almost always my #1
goals.

But I was curious, in the community of c programmers, whether Unions
had an honored place in the engineer''s toolkit, or whether they were
more like an old awl kicking around the dark corners of the box. Feel
free to provide instructive examples of great moments in Union history!

IMHO unions are closer to the dark corners than to the
well-lit top drawer, but they''re a tool that would be missed
if someone borrowed them and forgot to return them to your
tool chest.

"Space-saving" has become something of a dirty word, along
with "efficiency." But this is largely a backlash against
excess, against the ritualistic drive to save one more byte
or one more microsecond in a "Hello, world!" program. There
remain situations where savings are important.

And among those, space-saving situations arise more often
than (justifiable) time-saving situations. You''ve mentioned
the use of unions in "poor man''s O-O" polymorphic situations,
and it''s easy to see that in a rich object hierarchy with a
lot of more-than-kin-but-less-than-kind relationships the space
savings could be huge. Also, in such situations space savings
can easily equate to time savings: compared to the modern CPU,
memory is d-o-g s-l-o-w and getting slower (we reward our memory
manufacturers for density and for cost, not for speed). If you
can pack four Thing instances into a cache line instead of just
two, you stand a chance of cutting the cache miss rate in half
and making your program 30-60% faster. That sort of efficiency
isn''t in the "dirty word" department; it''s nothing like the
foolish exercise of shaving a microsecond off a loop that will
run three times total.

You mentioned device drivers. There''s a field that''s ripe
for polymorphic programming: You''ll have a generic framework
that bridges between the device-blind and device-aware parts
of the system, and maybe in the device-aware layer you''ll have
further abstraction (we''re in the SCSI driver, but are we
talking to a disk or to a tape?). A convenient way to build
such frameworks is to let the lowest-level pieces build structs
with all the information their specific devices need, and then
hand them off to higher-level layers that are unaware of the
specifics. This is polymorphism in action, chum, and unions
are a fine way to achieve it. Not the only way, but a good one.

So, always look for the union label.

--
Eric Sosman
es*****@acm-dot-org.invalid


bluejack <bl******@gmail.comwrote:

>Feel free to provide instructive examples of great moments in Union
history!

Some Internet sockets implementations used to use a union like this
(some probably still do) for IPv4 addresses:

struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
}
#define s_addr S_un.S_addr

This way you could look at the internet address as 4 8-bit chunks, 2
16-bit chunks, or 1 32-bit chunk (using the define to access it as
"foo.s_addr".)

Turns out most people used the 32-bit representation, and under Linux,
anyway, the union is long gone:

typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};

But looking down the code a little more, union is used again for the
IPv6 stuff:

/* IPv6 address */
struct in6_addr
{
union
{
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};

-Beej


bluejack wrote:

A recent post asking for help with unions reminded me of this
component of the C language that I have only used a couple of times,
and those almost entirely out of personal whim -- Unions for the sake
of Unions simply because I wanted to see one in action.

<snip>

>
But I was curious, in the community of c programmers, whether Unions
had an honored place in the engineer''s toolkit, or whether they were
more like an old awl kicking around the dark corners of the box. Feel
free to provide instructive examples of great moments in Union history!

One large swag of code that uses (big) unions is the standard Unix
windowing environment, Xlib. All X events are represented as structures
within one union, where the first structure member is the event ID.

--
Ian Collins.


这篇关于真实联盟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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