H
Hallvard B Furuseth
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 types73)
- (...)
- 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.
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 types73)
- (...)
- 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.