Re: Uninitialized memory, malloc and unsigned char



Tim Woodall <devn...@xxxxxxxxxxxxx> wrote:
On Mon, 26 May 2008 00:34:49 -0700 (PDT), Jun Woong <wo...@xxxxxxxxx> wrote:
[...]
Nope. unsigned char is not allowed to have padding bits [*], which
means every possible bit-pattern is guaranteed to contribute to a
value.

[*] To be precise, if unsigned char (byte) has padding bits on a
machine, all other types also have to have them at the same bit-
position and a C implementation on that machine is required to make
them invisible to a user.

Yes, that's true. But would the following implementation be compatible
with the standard?

1. All memory at startup is in an indeterminate state.
2. The first access to each byte of memory defines whether it is read
only memory (a read) or read/write memory (a write).

There are no trap representations here in unsigned char. A read of
uninitialized memory will succeed and return an unspecified value but
any further write to that memory will then fail.


I don't see any guarantee from the standard that renders this
implementation to be conforming. If I understand your example, on it
the following (conforming) code must fail:

int a; /* in an indeterminate state */
unsigned char *uc = (void *)&a;
*uc; /* read an unspecified value */
a = 0; /* must fail! */

[...]
Validity of these two assignments depends on whether the struct value
can be indeterminate even when all of its members cannot. A relevant
wording is 6.2.6.1p6 (I quoted the whole paragraph to preserve the
context):

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. The value of a structure or union object is
never a trap representation, even though the value of a member of
the structure or union object may be a trap representation.

I think this ensures that the holes between sturct members do not
affect validity of the struct.

I'm surprised, however, to see the last sentence quoted above. That
seems to say that an implementation is prohibited from incurring
undefined behavior even when the member of a struct being assigned
has a trap representation and it does the member-to-member
assignment. Is this really intended, or does the sentence in question
have to read as

The value of a structure or union object is not allowed to have a
trap representation unless one of its members has a trap
representation.

?

I missed that. However, I think the standard makes sense here.

This wording means that you can copy a structure and then access the
members that are known to be defined without invoking undefined
behaviour. Only if you attempt to access the individual undefined
members will you invoke undefined behaviour.

void eg(void)
{
struct st x;
x.val1 = 7;

function_that_only_uses_val1_in_struct(x); /* Pass by value */

}


My belief was that, in order not to invoke UB every member of a
struct needed to be initialized properly. I've always thought that
the above wording meant just that paddings between members are not
allowed to affect validity of the whole struct.

What the current standard guarantees now is that the following code
would never fail:

void foo(void)
{
struct { ... } x, y;
x = y;
}

I don't see why such an erroneous code should be endorsed.

If it's general to initialize only a part of a struct before using
the wording in question should be restricted more than it is, I
think.


--
Jun, Woong (woong at icu.ac.kr)
Samsung Electronics Co., Ltd.

``All opinions expressed are mine, and do not represent
the official opinions of any organization.''
.



Relevant Pages

  • Re: Uninitialized memory, malloc and unsigned char
    ... struct s; ... the structure or union object may be a trap representation. ... I think this ensures that the holes between sturct members do not ...
    (comp.std.c)
  • Re: Uninitialized memory, malloc and unsigned char
    ... undefined behavior even when the member of a struct being assigned ... has a trap representation and it does the member-to-member ... All the standard does is require that structure members be copied by ... something analogous to memcpy rather than member assignment. ...
    (comp.std.c)
  • Re: Struct assignment
    ... to copy padding bytes and padding bits. ... the value of a struct, and might not be copied -- as they ... The value of a structure or union object is never a trap ... or union object may be a trap representation. ...
    (comp.lang.c)
  • Re: Uninitialized memory, malloc and unsigned char
    ... struct s; ... the structure or union object may be a trap representation. ... I think this ensures that the holes between sturct members do not ...
    (comp.std.c)
  • Re: Passing structs by value
    ... > The value of a struct or union object is never a trap ... > union object may be a trap representation. ...
    (comp.lang.c)