结构和联合中的字节对齐 [英] byte alignment in structures and unions

查看:62
本文介绍了结构和联合中的字节对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨!


我想将数字129(二进制10000001)分配给4字节长的MSB(大多数

有效字节)并留下其他较低的字节 -

圆滑!


-正常奔腾的工作(... endian)


我想用不使用shift的代码(<<<<<<<<<<<<<<<<<<<<<<<<<<"编译器必须完成工作,我将介绍

适当的结构和联合。

#include< stdio.h>


struct each_of_four {

unsigned char byte0;

unsigned char byte1;

unsigned char byte2;

unsigned char byte3;

}

/ * __ attribute __((打包))* /

;


union align_long_and_each_of_four {

long dummy; / * 4字节* /

struct each_of_four四;

}

/ * __ attribute __((打包))* /

;

int main(无效)

{

long val; // 4个字节


/ ******************测试A:编译器错误 - 为什么?

********************* /

((union align_long_and_each_of_four)val).four.byte3 =(未签名

char)129;


#define FUNNY_NUMBER((union align_long_and_each_of_four)\

(const long)((129<< ; 24)|(val& 16777215)))。four.byte3

// 16777215 = 2 ^ 24-1


printf(" test FUNNY_NUMBER:%d \ n",FUNNY_NUMBER);


/ ******************测试B:编译器错误 - 为什么?

********************* /

((union align_long_and_each_of_four)val).four.byte3 = FUNNY_NUMBER;


返回0;

}

编译器错误报告--->

test_align.c:25:错误:赋值时左值无效

test_align.c:39:错误:赋值时左值无效


如何修复??


谢谢

anon.asdf

Hi!

I want to assign the number 129 (binary 10000001) to the MSB (most
significant byte) of a 4-byte long and leave the other lower bytes in-
tact!

-working on normal pentium (...endian)

I want to do it with code that does NOT use shifts (<<) , bit-
operations (| &) !!
So the compiler will have to do the work and I''ll introduce
appropriate structs and unions.
#include <stdio.h>

struct each_of_four {
unsigned char byte0;
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
}
/*__attribute__ ((packed))*/
;

union align_long_and_each_of_four {
long dummy; /* 4 bytes */
struct each_of_four four;
}
/*__attribute__ ((packed))*/
;
int main(void)
{
long val; // 4 bytes

/****************** TEST A: COMPILER ERROR - WHY?
*********************/
((union align_long_and_each_of_four) val).four.byte3 = (unsigned
char) 129;


#define FUNNY_NUMBER ((union align_long_and_each_of_four) \
(const long) ((129<<24) | (val & 16777215))).four.byte3
// 16777215 = 2^24-1

printf("test FUNNY_NUMBER: %d\n", FUNNY_NUMBER);

/****************** TEST B: COMPILER ERROR - WHY?
*********************/
((union align_long_and_each_of_four) val).four.byte3 = FUNNY_NUMBER;

return 0;
}
Compiler error report--->
test_align.c:25: error: invalid lvalue in assignment
test_align.c:39: error: invalid lvalue in assignment

How can this be fixed??

Thanks
anon.asdf

解决方案

/ ******************测试A:编译器错误 - 为什么?
/****************** TEST A: COMPILER ERROR - WHY?

********************* /

((union align_long_and_each_of_four) )val).four.byte3 =(unsigned

char)129;
*********************/
((union align_long_and_each_of_four) val).four.byte3 = (unsigned
char) 129;



这里非常有趣的是,以下代码可以正常工作!


{

union align_long_and_each_of_four tmp;


tmp.four.byte3 =(unsigned char)129;

}


但是仍然 - 如何修复测试A中的编译器错误?


The really interesting here, is that the following code DOES work!

{
union align_long_and_each_of_four tmp;

tmp.four.byte3 = (unsigned char) 129;
}

But still - how can the compiler error in TEST A be fixed??


一个******* @ gmail.com 在08/09/07 13:38写道:
an*******@gmail.com wrote On 08/09/07 13:38,:

嗨!


我想将数字129(二进制10000001)分配给4字节长的MSB(大多数

有效字节),让另一个更低字节在 -

圆滑!


-正常奔腾的工作(... endian)


我想要的用不使用shift的代码(<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"工作,我会介绍

适当的结构和工会。


#includ e< stdio.h>


struct each_of_four {

unsigned char byte0;

unsigned char byte1;

unsigned char byte2;

unsigned char byte3;

}

/ * __ attribute __((packed))* /

;


union align_long_and_each_of_four {

long dummy; / * 4字节* /

struct each_of_four四;

}

/ * __ attribute __((打包))* /

;


int main(无效)

{

long val; // 4个字节


/ ******************测试A:编译器错误 - 为什么?

********************* /

((union align_long_and_each_of_four)val).four.byte3 =(未签名

char)129;


#define FUNNY_NUMBER((union align_long_and_each_of_four)\

(const long)((129<< ; 24)|(val& 16777215)))。four.byte3

// 16777215 = 2 ^ 24-1


printf(" test FUNNY_NUMBER:%d \ n",FUNNY_NUMBER);


/ ******************测试B:编译器错误 - 为什么?

********************* /

((union align_long_and_each_of_four)val).four.byte3 = FUNNY_NUMBER;
Hi!

I want to assign the number 129 (binary 10000001) to the MSB (most
significant byte) of a 4-byte long and leave the other lower bytes in-
tact!

-working on normal pentium (...endian)

I want to do it with code that does NOT use shifts (<<) , bit-
operations (| &) !!
So the compiler will have to do the work and I''ll introduce
appropriate structs and unions.
#include <stdio.h>

struct each_of_four {
unsigned char byte0;
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
}
/*__attribute__ ((packed))*/
;

union align_long_and_each_of_four {
long dummy; /* 4 bytes */
struct each_of_four four;
}
/*__attribute__ ((packed))*/
;
int main(void)
{
long val; // 4 bytes

/****************** TEST A: COMPILER ERROR - WHY?
*********************/
((union align_long_and_each_of_four) val).four.byte3 = (unsigned
char) 129;


#define FUNNY_NUMBER ((union align_long_and_each_of_four) \
(const long) ((129<<24) | (val & 16777215))).four.byte3
// 16777215 = 2^24-1

printf("test FUNNY_NUMBER: %d\n", FUNNY_NUMBER);

/****************** TEST B: COMPILER ERROR - WHY?
*********************/
((union align_long_and_each_of_four) val).four.byte3 = FUNNY_NUMBER;



因为你不能转换为联盟(或结构)或来自联盟(或结构)

类型:它们不是标量类型 (6.5.4p2)。请记住

一个演员是一个转换一个值的运算符,而不是一个神奇的让'假装构造。在任何情况下,由演员操作员产生的

值与由(例如)一元减号运算符产生的

a值相同:

你不能写`-x = 42''。

Because you cannot cast to or from a union (or struct)
type: They are not "scalar types" (6.5.4p2). Keep in mind
that a cast is an operator that converts a value, not a
magical "let''s pretend" construct. And in any case, the
value produced by a cast operator has the same status as
a value produced by (for example) a unary minus operator:
You cannot write `-x = 42'', either.


返回0;

}


编译错误报告--->

test_align.c:25:错误:赋值中左值无效

test_align.c:39:错误:分配中的左值无效


如何修复?
return 0;
}
Compiler error report--->
test_align.c:25: error: invalid lvalue in assignment
test_align.c:39: error: invalid lvalue in assignment

How can this be fixed??



单程是


((unsigned char *)& val)[3] = 129;


当然,如果'val''不是四个字节

长,MSB处于第四位,这就失败了。更好的方法是


val =(val& 0xffffffUL)| (129UL<< 24);


(是的,我知道你说你不想使用班次或

按位运算符。艰难:无论如何,这是更好的方式。)


最后的想法:*每个*解决方案都存在问题

它对于什么做出了不可移植的假设当你到达并敲定其中一个
字节时,就会发生'val''的价值。当你这样做时,你已经离开了

C语言的保证,并且需要在没有他们保护的情况下进入未知领域。 unsigned long会让事情好一些,但是......


-
Er ********* @ sun.com


On Thu ,2007年8月9日17:38:22 +0000,anon.asdf写道:
On Thu, 09 Aug 2007 17:38:22 +0000, anon.asdf wrote:

嗨!


我想要将数字129(二进制10000001)分配给4字节长的MSB(最多

有效字节),并将其他较低字节留在-B / B
! />

-正常奔腾的工作(... endian)


我想用不使用移位的代码(<< ),位 -

操作(|&)!!
Hi!

I want to assign the number 129 (binary 10000001) to the MSB (most
significant byte) of a 4-byte long and leave the other lower bytes in-
tact!

-working on normal pentium (...endian)

I want to do it with code that does NOT use shifts (<<) , bit-
operations (| &) !!



l%= 0x01000000;

l + = 129 * 0x01000000;

无论字节顺序如何,这都有效。

l %= 0x01000000;
l += 129 * 0x01000000;
This works regardless of endianness.


因此编译器必须完成工作,我将介绍

适当的结构和联合。

#include< stdio.h>


struct each_of_four {

unsigned char byte0;

unsigned char byte1;

unsigned char byte2;

unsigned char byte3;

}

/ * __ attribute __((packed))* /
So the compiler will have to do the work and I''ll introduce
appropriate structs and unions.
#include <stdio.h>

struct each_of_four {
unsigned char byte0;
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
}
/*__attribute__ ((packed))*/



unsigned char bytes [4]出了什么问题,导致你注释掉的东西会在某个地方发生同样的事情,但是在

标准C?

What was wrong with unsigned char bytes[4], which causes the same
thing that the stuff you commented out would do somewhere, but in
standard C?


;
;


union align_long_and_each_of_four {

long dummy; / * 4字节* /

struct each_of_four四;

}

/ * __ attribute __((打包))* /

;
union align_long_and_each_of_four {
long dummy; /* 4 bytes */
struct each_of_four four;
}
/*__attribute__ ((packed))*/
;



{long dummy; unsigned char four [4]; }?

What was wrong with { long dummy; unsigned char four[4]; }?


int main(void)

{

long val; // 4个字节


/ ******************测试A:编译器错误 - 为什么?

********************* /

((union align_long_and_each_of_four)val).four.byte3 =(未签名

char)129;
int main(void)
{
long val; // 4 bytes

/****************** TEST A: COMPILER ERROR - WHY?
*********************/
((union align_long_and_each_of_four) val).four.byte3 = (unsigned
char) 129;



因为演员的结果不是左值。

尝试

((unsigned char * )& val)[3] = 129;

不需要工会,也不需要结构。

Because the result of a cast isn''t a lvalue.
Try
((unsigned char *)&val)[3] = 129;
No unions and no struct needed.


#define FUNNY_NUMBER((union align_long_and_each_of_four) \\ /
(const long)((129 << 24)|(val& 16777215)))。four.byte3
#define FUNNY_NUMBER ((union align_long_and_each_of_four) \
(const long) ((129<<24) | (val & 16777215))).four.byte3



Didn''你说你不想使用按位操作吗?

-

Army1987(用电子邮件替换NOSPAM)

没有人通过辞职来赢得比赛。 - S. Tartakower

Didn''t you say you didn''t want to use bitwise operations?
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower


这篇关于结构和联合中的字节对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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