通过union访问char作为int [英] accessing char as int through union

查看:70
本文介绍了通过union访问char作为int的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码有效吗?通常必须通过与存储的相同类型访问值
,但对于通过字符类型存储的数据存在例外
。我不确定在这种情况下是否适用




#include< limits.h>


unsigned foo(void){

static const union {

unsigned char str [4];

unsigned i;

} val = {{1,2,3,4}};

if(sizeof(int)== 4&& CHAR_BIT == 8&& UINT_MAX == 0xFFFFFFFFUL)

返回val.i

返回0;

}


As据我所知,相关的标准是在C99 6.5 p6-7:


6.5表达式


6.有效类型用于访问其存储值的对象是

对象的声明类型(如果有的话)。(72)如果值存储在

中,则没有声明类型的对象通过具有类型

且不是字符类型的左值,则左值的类型成为该访问的对象的有效类型以及随后的

访问不修改商店d值。如果使用memcpy或memmove将值复制到没有声明类型的对象中,或者将

复制为字符类型数组,则<的有效类型为

用于该访问的修改对象以及后续访问

不修改该值的对象的有效类型

该值是复制,如果有的话。对于没有声明类型的

对象的所有其他访问,对象的有效类型是

,只是用于访问的左值的类型。


7.对象的存储值只能由左值

表达式访问,该表达式具有以下类型之一:(73)

- (...)

- 一种聚合或联合类型,包括其成员中的上述

类型之一(包括递归地,

subaggregate或者包含union),或者

- 一个字符类型。


脚注:

72)分配对象没有声明的类型。

73)此列表的目的是指定一个对象可能或可能没有别名的情况




-

Hallvard

Is the code below valid? Generally a value must be accessed
through the same type it was stored as, but there is an exception
for data stored through a character type. I''m not sure if that
applies in this case though:

#include <limits.h>

unsigned foo(void) {
static const union {
unsigned char str[4];
unsigned i;
} val = { { 1, 2, 3, 4 } };
if (sizeof(int) == 4 && CHAR_BIT == 8 && UINT_MAX == 0xFFFFFFFFUL)
return val.i
return 0;
}

As far as I can tell, the relevant standardese is in C99 6.5 p6-7:

6.5 Expressions

6. The effective type of an object for an access to its stored value is
the declared type of the object, if any.(72) If a value is stored into
an object having no declared type through an lvalue having a type
that is not a character type, then the type of the lvalue becomes the
effective type of the object for that access and for subsequent
accesses that do not modify the stored value. If a value is copied
into an object having no declared type using memcpy or memmove, or is
copied as an array of character type, then the effective type of the
modified object for that access and for subsequent accesses that do
not modify the value is the effective type of the object from which
the value is copied, if it has one. For all other accesses to an
object having no declared type, the effective type of the object is
simply the type of the lvalue used for the access.

7. An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:(73)
- (...)
- an aggregate or union type that includes one of the aforementioned
types among its members (including, recursively, a member of a
subaggregate or contained union), or
- a character type.

Footnotes:
72) Allocated objects have no declared type.
73) The intent of this list is to specify those circumstances in which
an object may or may not be aliased.

--
Hallvard

推荐答案



Hallvard B Furuseth写道:

Hallvard B Furuseth wrote:

以下代码是否有效?通常必须通过与存储的相同类型访问值
,但对于通过字符类型存储的数据存在例外
。我不确定在这种情况下是否适用




#include< limits.h>


unsigned foo(void){

static const union {

unsigned char str [4];

unsigned i;

} val = {{1,2,3,4}};

if(sizeof(int)== 4&& CHAR_BIT == 8&& UINT_MAX == 0xFFFFFFFFUL)

返回val.i

返回0;

}


As据我所知,相关的标准是在C99 6.5 p6-7:


6.5表达式


6.有效类型用于访问其存储值的对象是

对象的声明类型(如果有的话)。(72)如果值存储在

中,则没有声明类型的对象通过具有类型

且不是字符类型的左值,则左值的类型成为该访问的对象的有效类型以及随后的

accessse s不修改存储的值。如果使用memcpy或memmove将值复制到没有声明类型的对象中,或者将

复制为字符类型数组,则<的有效类型为

用于该访问的修改对象以及后续访问

不修改该值的对象的有效类型

该值是复制,如果有的话。对于没有声明类型的

对象的所有其他访问,对象的有效类型是

,只是用于访问的左值的类型。


7.对象的存储值只能由左值

表达式访问,该表达式具有以下类型之一:(73)

- (...)

- 一种聚合或联合类型,包括其成员中的上述

类型之一(包括递归地,

subaggregate或者包含union),或者

- 一个字符类型。


脚注:

72)分配对象没有声明的类型。

73)此列表的目的是指定一个对象可能或可能没有别名的情况




-

Hallvard
Is the code below valid? Generally a value must be accessed
through the same type it was stored as, but there is an exception
for data stored through a character type. I''m not sure if that
applies in this case though:

#include <limits.h>

unsigned foo(void) {
static const union {
unsigned char str[4];
unsigned i;
} val = { { 1, 2, 3, 4 } };
if (sizeof(int) == 4 && CHAR_BIT == 8 && UINT_MAX == 0xFFFFFFFFUL)
return val.i
return 0;
}

As far as I can tell, the relevant standardese is in C99 6.5 p6-7:

6.5 Expressions

6. The effective type of an object for an access to its stored value is
the declared type of the object, if any.(72) If a value is stored into
an object having no declared type through an lvalue having a type
that is not a character type, then the type of the lvalue becomes the
effective type of the object for that access and for subsequent
accesses that do not modify the stored value. If a value is copied
into an object having no declared type using memcpy or memmove, or is
copied as an array of character type, then the effective type of the
modified object for that access and for subsequent accesses that do
not modify the value is the effective type of the object from which
the value is copied, if it has one. For all other accesses to an
object having no declared type, the effective type of the object is
simply the type of the lvalue used for the access.

7. An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:(73)
- (...)
- an aggregate or union type that includes one of the aforementioned
types among its members (including, recursively, a member of a
subaggregate or contained union), or
- a character type.

Footnotes:
72) Allocated objects have no declared type.
73) The intent of this list is to specify those circumstances in which
an object may or may not be aliased.

--
Hallvard



是的,该代码有效。事实上,您的代码等于以下

IA-32机器:

------------

unsigned j =''\ x04 \ x03 \ x02 \ x01'';

------------

但是这是依赖于拱形的。

ps。您的代码中错过了逗号。 ; -p

Yeah, that code is valid. In fact, your code equals to the following on
IA-32 machines:
------------
unsigned j=''\x04\x03\x02\x01'';
------------
But that is arch-dependent.
ps. a comma is missed in your code. ;-p




Cong Wang写道:

Cong Wang wrote:

Hallvard B Furuseth写道:
Hallvard B Furuseth wrote:

下面的代码是否有效?通常必须通过与存储的相同类型访问值
,但对于通过字符类型存储的数据存在例外
。我不确定在这种情况下是否适用




#include< limits.h>


unsigned foo(void){

static const union {

unsigned char str [4];

unsigned i;

} val = {{1,2,3,4}};

if(sizeof(int)== 4&& CHAR_BIT == 8&& UINT_MAX == 0xFFFFFFFFUL)

返回val.i

返回0;

}


As据我所知,相关的标准是在C99 6.5 p6-7:


6.5表达式


6.有效类型用于访问其存储值的对象是

对象的声明类型(如果有的话)。(72)如果值存储在

中,则没有声明类型的对象通过具有类型

且不是字符类型的左值,则左值的类型成为该访问和后续序列的对象的有效类型

t

访问不会修改存储的值。如果使用memcpy或memmove将值复制到没有声明类型的对象中,或者将

复制为字符类型数组,则<的有效类型为

用于该访问的修改对象以及后续访问

不修改该值的对象的有效类型

该值是复制,如果有的话。对于没有声明类型的

对象的所有其他访问,对象的有效类型是

,只是用于访问的左值的类型。


7.对象的存储值只能由左值

表达式访问,该表达式具有以下类型之一:(73)

- (...)

- 一种聚合或联合类型,包括其成员中的上述

类型之一(包括递归地,

subaggregate或者包含union),或者

- 一个字符类型。


脚注:

72)分配对象没有声明的类型。

73)此列表的目的是指定一个对象可能或可能没有别名的情况




-

Hallvard
Is the code below valid? Generally a value must be accessed
through the same type it was stored as, but there is an exception
for data stored through a character type. I''m not sure if that
applies in this case though:

#include <limits.h>

unsigned foo(void) {
static const union {
unsigned char str[4];
unsigned i;
} val = { { 1, 2, 3, 4 } };
if (sizeof(int) == 4 && CHAR_BIT == 8 && UINT_MAX == 0xFFFFFFFFUL)
return val.i
return 0;
}

As far as I can tell, the relevant standardese is in C99 6.5 p6-7:

6.5 Expressions

6. The effective type of an object for an access to its stored value is
the declared type of the object, if any.(72) If a value is stored into
an object having no declared type through an lvalue having a type
that is not a character type, then the type of the lvalue becomes the
effective type of the object for that access and for subsequent
accesses that do not modify the stored value. If a value is copied
into an object having no declared type using memcpy or memmove, or is
copied as an array of character type, then the effective type of the
modified object for that access and for subsequent accesses that do
not modify the value is the effective type of the object from which
the value is copied, if it has one. For all other accesses to an
object having no declared type, the effective type of the object is
simply the type of the lvalue used for the access.

7. An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:(73)
- (...)
- an aggregate or union type that includes one of the aforementioned
types among its members (including, recursively, a member of a
subaggregate or contained union), or
- a character type.

Footnotes:
72) Allocated objects have no declared type.
73) The intent of this list is to specify those circumstances in which
an object may or may not be aliased.

--
Hallvard



是的,该代码有效。事实上,您的代码等于以下

IA-32机器:

------------

unsigned j =''\ x04 \ x03 \ x02 \ x01'';

------------

但是这是依赖于拱形的。

ps。您的代码中错过了逗号。 ; -p


Yeah, that code is valid. In fact, your code equals to the following on
IA-32 machines:
------------
unsigned j=''\x04\x03\x02\x01'';
------------
But that is arch-dependent.
ps. a comma is missed in your code. ;-p



对不起,分号,不是逗号。我错了。 ;-(


Sorry, a semicolon, not a comma. I mistyped that. ;-(


Cong Wang写道:
Cong Wang writes:

Hallvard B Furuseth写道:
Hallvard B Furuseth wrote:

>下面的代码是否有效?(...)
unsigned foo(void){
static const union {
unsigned char str [4];
未签名的i;
} val = {{1,2,3,4}};
if(sizeof(int)== 4&& CHAR_BIT = = 8&& UINT_MAX == 0xFFFFFFFFUL)
返回val.i
返回0;
}

据我所知,相关的标准是在C99 6.5 p6-7:
(...)
>Is the code below valid? (...)
unsigned foo(void) {
static const union {
unsigned char str[4];
unsigned i;
} val = { { 1, 2, 3, 4 } };
if (sizeof(int) == 4 && CHAR_BIT == 8 && UINT_MAX == 0xFFFFFFFFUL)
return val.i
return 0;
}

As far as I can tell, the relevant standardese is in C99 6.5 p6-7:
(...)



是的,该代码有效。


Yeah, that code is valid.



好​​。

Good.


实际上,你的代码在IA-32机器上等于以下内容:

unsigned j =' '\ x04 \ x03 \ x02 \ x01'';

但这是与拱形相关的。
In fact, your code equals to the following on IA-32 machines:
unsigned j=''\x04\x03\x02\x01'';
But that is arch-dependent.



是的,但是那么我不妨写一下0x01020304。


我一直在寻找一种符合标准的编译时方式来设置字节顺序

的整数。上面的联合hack并不一定会编译出编译时优化的编译时_constant_,但是至少它不需要运行时初始化。

-

Hallvard

Yeah, but then I might as well write 0x01020304.

I was looking for a conformant, compile-time way to set the endianness
of an integer. The union hack above doesn''t necessarily make a
compile-time _constant_ which the compiler will optimize away,
but at least it doesn''t require run-time initialization.
--
Hallvard


这篇关于通过union访问char作为int的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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