I have the following question:
As I understand the standard, a struct (properly defined) is an
object, and it's members are objects as well.
given the following
struct s_t
{
char c[11];
double d;
} o_s;
o_s is an object of type struct s_t,
o_s.d is an object of type double,
c is an array of objects of type char.
first question: Did I get this right ?
OK, now:
(I deliberately choose 11 for the cahr array size, because in that
case there will be most likely padding bytes between o_s.c and
o_s.d)
Second question:
Assumed there _are_ padding bytes.
Is an implementation allowed, given the following statement:
o_s.d = 1.2345;
to change the padding bytes ?
Or more general:
Is an implementation allowed to modify any storage which belongs to
a program (the space for the struct could have been malloc()ed) in
an assignment statement except the object it assigns to?
IOW Is there a difference in the assignment process between
o_s.d = 1.2345; in the above and
double v_d;
v_d = 1.2345;
Kind regards
--
Robert Stankowic
pcdo...@netway.at
"The regular early morning yell of horror" - Douglas Adams
The standard defines an object as a "region of data storage in the
execution environment, the contents of which can represent values"
[C99:3.14]. This is quite vague, for example the question arises whether
this is meant to imply that there are regions of data storage the
contents of which cannot represent values, and whether "region" is meant
to imply contiguous address space. Or for example in 6.2.4, the
"lifetime of an object" is defined as "the portion of program execution
during which storage is guaranteed to be reserved for it", which
somewhat clashes with the above definition; how can storage be reserved
for a "region of data storage"? This, and other wording in the standard
suggest that "object" actually is not the region of data storage itself,
but something in a seperate conceptual space with a mapping into data
storage, or address space.
Typically, in C standardese, "object" is used to denote the addressable
and contiguous (in address space) area of storage associated with an
lvalue, i.e. with the size associated with the type of the lvalue.
> given the following
>
> struct s_t
> {
> char c[11];
> double d;
> } o_s;
>
> o_s is an object of type struct s_t,
> o_s.d is an object of type double,
> c is an array of objects of type char.
>
> first question: Did I get this right ?
Yes. The array c itself is also an object, not just its members.
> OK, now:
> (I deliberately choose 11 for the cahr array size, because in that
> case there will be most likely padding bytes between o_s.c and
> o_s.d)
>
> Second question:
> Assumed there _are_ padding bytes.
> Is an implementation allowed, given the following statement:
> o_s.d = 1.2345;
> to change the padding bytes ?
C99:6.2.6.1p6 states: "When a value is stored in an object of structure
or union type, including in a member object, the bytes of the object
representation that correspond to any padding bytes take unspecified
values."
So, yes, I'd say that any store operation into a structure is allowed to
change the values of any of its padding bytes.
> Or more general:
> Is an implementation allowed to modify any storage which belongs to
> a program (the space for the struct could have been malloc()ed) in
> an assignment statement except the object it assigns to?
Not generally (although I think the standard actually doesn't explicitly
forbid it -- it only defines where side-effects may or must occur, but
doesn't say that these are the only side-effects that are allowed to
occur), but in the above example, yes.
> IOW Is there a difference in the assignment process between
> o_s.d = 1.2345; in the above and
> double v_d;
> v_d = 1.2345;
By what has been said above, yes, there may be a difference.
-- Niklas Matthies
[extensive and greatly appreciated explanation snipped]
thank you, Niklas, I think I got it.