VC环境下,全局变量或者局部变量,我们都知道需要4字节对齐,而结构内的变量呢?

lovessm 2004-12-28 01:26:00
结构内的变量的对齐和其他变量就不一样了。



/* 假设VC设置的结构对齐限制是8 */
struct struct_test
{
char c;
shor s;
int i;
}haha;

int main()
{
/* 。。。 */
return 0;
}

经过测试s的地址肯定能被2整除(也就是两字节对齐),而i肯定能被4整除(也就是4字节对齐)

编译器这样处理,又是为何?
...全文
734 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
lovessm 2004-12-28
  • 打赏
  • 举报
回复
winstonch, happy__888:
能否赏脸加一下偶的MSN(通过短消息发送给二位)
交个朋友吧。
还有详细的问题需要讨教!
winstonch 2004-12-28
  • 打赏
  • 举报
回复
处理局部变量时好象和结构体是一样的,我有点记不清了,当时我没太仔细研究,给下面具体做这个东西的人看了,我就是有一个模糊的概念,怎么想把这个东西搞的这么深,要写论文呀?
lovessm 2004-12-28
  • 打赏
  • 举报
回复
那ARMCC是如何处理变量对齐和结构内对齐的呢?
winstonch 2004-12-28
  • 打赏
  • 举报
回复
我看的就是ARM C的
lovessm 2004-12-28
  • 打赏
  • 举报
回复
to happy__888:
原来你是这个意思。

to winstock:
你知不知道ARM(编译器)处理结构内变量对齐时,是怎么处理的?
winstonch 2004-12-28
  • 打赏
  • 举报
回复
当然不是了,我是在2002年看的,那时候我还不会上csdn呢,而且那是面向一个嵌入式的应用.
你刚才说的我没仔细看,但我觉得是对的,描述的是不是足够精确严密在这上不用要求太高是吧?^-^
寻开心 2004-12-28
  • 打赏
  • 举报
回复
例子:
union {
struct sss {
char c1;
int i1;
char c2;
int i2;
char c3;
} ss[2];
BYTE b[22];
}
struct sss按照字节数目是11个,做个数组是22个
和下面的BYTE数组大小重合
如果struct sss的内部变量发生了4也好8也好的地址对齐
BYTE里面的内容必然和STRUCT sss里面的内容不对了

字节对齐不是必须的,是编译器优化的产物
看计算机原理里面内存寻址部分的设计就可以知道
连续的内存地址在实际的内存块上不连续,存在于不同的bank当中
这样的设计使得总线控制器在处理连续内存的操作的时候,减少寻址操作的次数
但是引发的麻烦就是在非bank数目倍数的地址的时候复杂一点。
winstonch 2004-12-28
  • 打赏
  • 举报
回复
好象不止是Intel Architechture这样,一些嵌入式的也是这样,我当时看的文档就不是Intel Architechture的,主要是在资源允许的情况下,这样做有助于提高效率的时候就会这样的
lovessm 2004-12-28
  • 打赏
  • 举报
回复
to winstonch():
冤枉呀,我是不肯定我的答案,希望和高手多讨论讨论,听听权威的解答, :-)

你的文档是不是我原来写的那个?/cy
lovessm 2004-12-28
  • 打赏
  • 举报
回复
to happy__888:
你说的union的情况,我不是很明白,觉得你说的有道理,你能不能说的更详细一点?不胜感激。
winstonch 2004-12-28
  • 打赏
  • 举报
回复
原来楼主是故意卖个官子呀,他是想给大家讲解这个问题,我还在这拼命的回忆当初看过的那个文档呢.

哎~哎~

lovessm 2004-12-28
  • 打赏
  • 举报
回复
以上是我说的,是原理也是实践,肯定没错,经过我的实践,我们能不能更加深入的从硬件角度考虑呢?

当然,我们讨论的都是Intel Architechture。
寻开心 2004-12-28
  • 打赏
  • 举报
回复
对齐是因为pc内部内存bank设置的原因
奇偶地址是不同的板块处理的
跨bank寻址麻烦,会降低效率
因此编译器把他们处理成bank的倍数为好

至于什么样子的数据会引发对齐
个人觉得, 只有与其他变量独立无关的变量,地址才可以用对齐的方法
否则如果你站在编译器的角度如何来解决变量之间的位置相关性呢

lovessm 2004-12-28
  • 打赏
  • 举报
回复
在结构中,每种变量都需要有自己的对齐,我们称为“自对齐”,当然,结构也有自己的自对齐;但是,结构的自对齐和其成员的对齐有着紧密的关系,即结构的自对齐就是其成员的自对齐的最大值;重要的一点,结构的自对齐需要受“最大对齐”的限制,这个最大对齐,就是我们在project settings里设置的那个structure alignment,当结构自对齐大于最大对齐时,就要以最大对齐作为结构的自对齐。

有了结构的自对齐,以后结构中包含结构变量,就好可以处理了,而且对于结构数组也有好处。
寻开心 2004-12-28
  • 打赏
  • 举报
回复
在union结构当中,如果struct sss,内部的变量做地址对齐
那么byte b[] 这样的变量如何和sturct sss里面的内容匹配呢

因为他们相关,这个时候对齐不可取,否则必然出错
kobefly 2004-12-28
  • 打赏
  • 举报
回复
楼主是强人
学习
lovessm 2004-12-28
  • 打赏
  • 举报
回复
winstonch()说的没错,你说的第一个,实际就是“基址”的概念。
寻开心 2004-12-28
  • 打赏
  • 举报
回复
n字节对齐的理由就不必说了

编译器安全的做法应该是只把独立的无关的变量做成n字节对齐的

否则一旦存在类型转换的情况,比如union结构里面的数据,或者是用户做强制类型转换的时候,数据结构非乱套不可

比如:
struct AAAA{
int i1;
char c1;
int i2;
char c2;
float f;
} a;
BYTE * p = (BYTE*) &a;
这样的结果来处理内部的数据的时候,无法解释了。

union {
struct sss {
.....
}
BYTE b[21];
}
也无法处理
lovessm 2004-12-28
  • 打赏
  • 举报
回复
to happy__888:
结构对齐的提出,决不是为了处理结构数组,而是为了处理结构中包含结构的情况。

对于结构数组就算没有结构对齐,照样可以寻址具体元素;

union类型的处理和结构内成员对齐,好象没什么关系吧,:-)
winstonch 2004-12-28
  • 打赏
  • 举报
回复
这种规则实际上比较麻烦的,函数参数也有这个问题.

好象是这样的(不一定正确,但是记得是有一种编译器是这样的):
1.第一个一定要从4字节开头.(这里对应c)
2.如果当前成员的前面成员没占满对齐位,则按照当前成员的对齐方式对齐(这里对应s short类型(2),那么在c后补一个字节)
...
说不下去了,以前看过这个文档,是递归方式描述的,现在实在表达不清了,先放在这儿吧,,希望能给大家点提示作用.

我回去再找一找,找到了再帖出来,与大家共享
加载更多回复(9)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧