发件人:Norman Diamond
新闻组:comp.lang.c
主题:回复:征集对C-FAQ提交的批评意见
日期:1994年9月22日 09:26:35 GMT
消息ID:<35rikb$4dt$1@usenet.pa.dec.com>

在文章<35qdf0$7iq@netaxs.com>中,Eric Raymond写道:
>A:在旧的字对齐机器上的大多数编译器中,除了数组的组成部分之外,每个C数据项
>都必须从一个字节地址开始,该地址是机器字大小的倍数(也就是说,每种类型都必须char
>“字对齐”)。随着古老的16位和36位机器的消亡,这种实现正变得越来越少。
>和36位机器消亡。
>“字对齐”)。随着古老的16位和36位机器消亡,这种实现正变得越来越少。

为了效率起见,通常这应该包括数组的组成部分,而C标准在这种情况下要求一点效率低下。我会删除“除了数组的组成部分之外”。而且,嵌入式系统正变得比以前更多。洗衣机和电饭锅过去没有这些东西。而嵌入式系统通常是用奇怪的自定义架构制成的。所以我认为“托管系统上的这种实现正变得罕见,尽管独立实现可能具有任意奇怪的要求。”“字对齐”)。随着古老的16位和36位机器消亡,这种实现正变得越来越少。

我读到委员会决定允许实现施加比必要条件更严格的对齐。我认为他们没有发布技术勘误,所以我认为他们的说法与标准相冲突,但还有什么新鲜事呢。不管怎样,请添加一个“至少”。

>struct/array/union类型的对齐方式与其最严格的成员对齐方式相同。

我读到委员会决定允许实现施加比必要条件更严格的对齐。我认为他们没有发布技术勘误,所以我认为他们的说法与标准相冲突,但还有什么新鲜事呢。不管怎样,请添加一个“至少”。

>每个
>连续位字段组的第一个成员通常是字对齐的,所有后面的
>成员会连续地打包到后面的字中(尽管ANSI C只要求后者用于
>小于字大小的位字段组)。

这里的“字”这个词含糊不清。该单位不必与int的大小相同。如果int具有字大小,而位字段的单位具有不同的尺寸,那么这里的“字”就不正确了。也许说“某个大小的单位”和“小于任何单位的大小”。

>Q:当一个类型出现在结构或数组中时,我如何计算它的“真实大小”(包括尾部填充)?
>它出现在结构或数组中?

正确的答案是“sizeof”运算符。它包括尾部填充。

>Q:我如何从结构中挤出填充以使其变小?
[...]
>一个简单的规则是在“自对齐”情况下最小化填充(并且在大多数其他情况下
>也不会造成危害),即按对齐要求递减的顺序排列结构成员。

不。按对齐要求递减的顺序排列结构成员。例如,一个47个字符的数组应该放在int之后,而不是反过来。而且你可能希望所有嵌套的结构都放在前面,即使它们相对较短,并且你想以一种最优化的方式排列它们,即使实现不强制额外的填充(这样它们在不强制填充的实现上确实是最优化的)。

还要注意,不同类型的指针可能有不同的尺寸,可能也有不同的对齐要求。指向函数类型、void或字符类型的指针“通常”至少和其他指针类型一样长,并且至少和它们一样严格,所以把它们放在前面“通常”至少是有利的。

指针应该放在double前面还是反过来?没有普遍的答案。

>同一大小的成员组内将不需要填充,

委员会说可能需要:-(

>任何组都不会要求前导填充;

这是正确的。标准禁止前导填充。

>Q:我如何完全控制结构在位级别的布局?
>A:这就是位字段的作用。将你的所有成员声明为位字段。

这仍然行不通,因为实现可能会将单位设置为1位,并在位之间插入任意填充。你能获得的 सर्वात全面的控制是通过放弃结构并使用字符数组。你仍然会在网络代码中遇到大端与小端的问题。

>关于位字段的说明:虽然现代编译器默认将它们设置为无符号,

也许吧;我从未尝试过。我建议总是指定所需的类型(int 或 unsigned)。

>Q:为什么我不能在我的网络上的异构机器之间来回传递结构?
>它们都是C,不是吗?

你甚至可能无法在单台机器上的两个程序之间做到这一点。一个编译器可能将int设置为16位,而另一个设置为32位。它们可能会在结构末尾填充不同的内容。

>Q:我从Pascal来到C,我怀念的一项功能是Pascal的`with'
>构造。C不应该有一个等效的功能吗?
>A:不,这太危险了。

算了吧,C是为那些喜欢冒险生活的人设计的。“这很危险”是包含它在C中的一个论据,而“这太危险了”是要求它在C中的一个论据。你真的忘记了C的精神吗?你最好删除这个问题和声称的答案。
--
<< 如果这是公司的意见,我将不允许发布。 >>
分段错误(加利福尼亚被解雇)