Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > passing uninitialised data

Reply
Thread Tools

passing uninitialised data

 
 
Barry Schwarz
Guest
Posts: n/a
 
      09-14-2012
On Fri, 14 Sep 2012 14:34:37 -0400, James Kuyper
<(E-Mail Removed)> wrote:

>On 09/14/2012 01:34 PM, Barry Schwarz wrote:
>> On Fri, 14 Sep 2012 11:48:26 -0400, James Kuyper
>> <(E-Mail Removed)> wrote:
>>
>>> On 09/14/2012 11:09 AM, Mark wrote:
>>>> Hello,
>>>>
>>>> I have quite a generic question. Suppose we work with fwrite(), or sendto()
>>>> (not C standard function, but I'll assume everyone knows it) or any other
>>>> API that takes a pointer to a buffer to trasnmit. When such a buffer is
>>>> unititialised, does it in some ways impose undefined behaviour?
>>>
>>>
>>>> I'm asking this, because when such code is run under 'valgrind' it reports a
>>>> lot about uninitiased memory or 'unaddressable values in syscalls' -- does
>>>> it imply such will act undefined due to uninit storages used as buffers?
>>>>
>>>> Would appreciate the comments on it. Thanks.
>>>
>>> "If an object that has automatic storage duration is not initialized
>>> explicitly, its value is indeterminate." (6.7.9p10)
>>>
>>> An indeterminate value is defined as "either an unspecified value or a
>>> trap representation" (3.19.2)
>>>
>>> "Certain object representations need not represent a value of the object
>>> type. If the stored value of an object has such a representation and is
>>> read by an lvalue expression that does not have character type, the
>>> behavior is undefined. ... Such a representation is called a trap
>>> representation." (6.2.6.1p5)
>>>
>>> So far, this looks bad. However, let's go a little further:
>>> The description of fwrite() says "... For each object, size calls are
>>> made to the fputc function, taking the values (in order) from an array
>>> of unsigned char exactly overlaying the object. ..." (7.21.8.2p1). In
>>> other words, it accesses the data using only lvalues of type unsigned
>>> char, a character type. Therefore, the undefined behavior mentioned in
>>> 6.2.6.1p5 doesn't apply.

>>
>> While an unsigned char cannot contain a trap value, I believe J.2,
>> even though it is not normative, gives the clearest statement of the
>> intent:
>>
>> "The behavior is undefined in the following circumstances: ... The
>> value of an object with automatic storage duration is used while it is
>> indeterminate."

>
>You might be right about the intent, but if so, what significance should
>we attach to the fact that 6.2.6.1p5 goes out of its way to say "that
>does not have character type"? If it doesn't mean that accesses through
>lvalues of character type are safe, what does it mean? If such accesses
>were not intended to be safe, why bother writing that phrase at all? The
>passage would be easier to read, write, and understand without that
>phrase, so I doubt that the phrase's presence was a mere accident.


I believe p5 is providing a definition of trap representation (and the
fact that unsigned char cannot have one) rather than limiting what
behavior is undefined.

--
Remove del for email
 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      09-17-2012
On 09/14/2012 06:26 PM, Barry Schwarz wrote:
> On Fri, 14 Sep 2012 14:34:37 -0400, James Kuyper
> <(E-Mail Removed)> wrote:
>
>> On 09/14/2012 01:34 PM, Barry Schwarz wrote:
>>> On Fri, 14 Sep 2012 11:48:26 -0400, James Kuyper
>>> <(E-Mail Removed)> wrote:
>>>
>>>> On 09/14/2012 11:09 AM, Mark wrote:
>>>>> Hello,
>>>>>
>>>>> I have quite a generic question. Suppose we work with fwrite(), or sendto()
>>>>> (not C standard function, but I'll assume everyone knows it) or any other
>>>>> API that takes a pointer to a buffer to trasnmit. When such a buffer is
>>>>> unititialised, does it in some ways impose undefined behaviour?
>>>>
>>>>
>>>>> I'm asking this, because when such code is run under 'valgrind' it reports a
>>>>> lot about uninitiased memory or 'unaddressable values in syscalls' -- does
>>>>> it imply such will act undefined due to uninit storages used as buffers?
>>>>>
>>>>> Would appreciate the comments on it. Thanks.
>>>>
>>>> "If an object that has automatic storage duration is not initialized
>>>> explicitly, its value is indeterminate." (6.7.9p10)
>>>>
>>>> An indeterminate value is defined as "either an unspecified value or a
>>>> trap representation" (3.19.2)
>>>>
>>>> "Certain object representations need not represent a value of the object
>>>> type. If the stored value of an object has such a representation and is
>>>> read by an lvalue expression that does not have character type, the
>>>> behavior is undefined. ... Such a representation is called a trap
>>>> representation." (6.2.6.1p5)
>>>>
>>>> So far, this looks bad. However, let's go a little further:
>>>> The description of fwrite() says "... For each object, size calls are
>>>> made to the fputc function, taking the values (in order) from an array
>>>> of unsigned char exactly overlaying the object. ..." (7.21.8.2p1). In
>>>> other words, it accesses the data using only lvalues of type unsigned
>>>> char, a character type. Therefore, the undefined behavior mentioned in
>>>> 6.2.6.1p5 doesn't apply.
>>>
>>> While an unsigned char cannot contain a trap value, I believe J.2,
>>> even though it is not normative, gives the clearest statement of the
>>> intent:
>>>
>>> "The behavior is undefined in the following circumstances: ... The
>>> value of an object with automatic storage duration is used while it is
>>> indeterminate."

>>
>> You might be right about the intent, but if so, what significance should
>> we attach to the fact that 6.2.6.1p5 goes out of its way to say "that
>> does not have character type"? If it doesn't mean that accesses through
>> lvalues of character type are safe, what does it mean? If such accesses
>> were not intended to be safe, why bother writing that phrase at all? The
>> passage would be easier to read, write, and understand without that
>> phrase, so I doubt that the phrase's presence was a mere accident.

>
> I believe p5 is providing a definition of trap representation (and the
> fact that unsigned char cannot have one) rather than limiting what
> behavior is undefined.


Even if your interpretation is correct, then 6.2.6.1p5 still doesn't
give such code undefined behavior, because in that case, the values can
only be unspecified, not trap representations, so the behavior of the
call to fwrite() is still defined.

As of C2011, the phrase "trap representation" is no longer in italics in
that section, and 3.19.4p1 is now the place where that phrase is
defined. That definition is "an object representation that need not
represent a value of the object type". It says nothing to exclude
character types, and the fact that, under certain circumstances, a trap
representation can result in undefined behavior, is not part of the
definition. I believe that this is not a change in the meaning of "trap
representation", but merely a clarification of something that C99 said
less clearly. The first and last sentences of that clause are now
redundant with 3.19.4p1, and could be removed; if so, "such a
representation" would have to be replaced with "a trap representation",
which would actually make the meaning clearer. Not naming the concept
until after it has been used several times was always rather clumsy writing.

6.2.6.1p5 is (now) solely about the circumstances under which a trap
representation can lead to undefined behavior. Reading one though an
lvalue of character type isn't one of them. The behavior of the fwrite()
call is defined by 7.21.8.2 even if the buffer is uninitialized: either
the specified number of bytes will be written from that buffer, or an
error code indicating an I/O error will be returned. If successful, the
actual values written to the file are unspecified, but if written and
read back using a binary stream, they must compare equal to the
unspecified values in the buffer (7.21.2p3). No matter what those values
are, fwrite() must return (after an unspecified amount of time, the same
as any call to fwrite() with defined behavior), and the succeeding lines
in the program will be executed. None of those things would be
guaranteed if the behavior were undefined.


 
Reply With Quote
 
 
 
 
Shao Miller
Guest
Posts: n/a
 
      12-18-2012
On 12/17/2012 14:52, Tim Rentsch wrote:
> Barry Schwarz <(E-Mail Removed)> writes:
>
>> On Fri, 14 Sep 2012 11:48:26 -0400, James Kuyper
>> <(E-Mail Removed)> wrote:
>>
>>> On 09/14/2012 11:09 AM, Mark wrote:
>>>> Hello,
>>>>
>>>> I have quite a generic question. Suppose we work with fwrite(), or sendto()
>>>> (not C standard function, but I'll assume everyone knows it) or any other
>>>> API that takes a pointer to a buffer to trasnmit. When such a buffer is
>>>> unititialised, does it in some ways impose undefined behaviour?
>>>
>>>
>>>> I'm asking this, because when such code is run under 'valgrind' it reports a
>>>> lot about uninitiased memory or 'unaddressable values in syscalls' -- does
>>>> it imply such will act undefined due to uninit storages used as buffers?
>>>>
>>>> Would appreciate the comments on it. Thanks.
>>>
>>> "If an object that has automatic storage duration is not initialized
>>> explicitly, its value is indeterminate." (6.7.9p10)
>>>
>>> An indeterminate value is defined as "either an unspecified value or a
>>> trap representation" (3.19.2)
>>>
>>> "Certain object representations need not represent a value of the object
>>> type. If the stored value of an object has such a representation and is
>>> read by an lvalue expression that does not have character type, the
>>> behavior is undefined. ... Such a representation is called a trap
>>> representation." (6.2.6.1p5)
>>>
>>> So far, this looks bad. However, let's go a little further:
>>> The description of fwrite() says "... For each object, size calls are
>>> made to the fputc function, taking the values (in order) from an array
>>> of unsigned char exactly overlaying the object. ..." (7.21.8.2p1). In
>>> other words, it accesses the data using only lvalues of type unsigned
>>> char, a character type. Therefore, the undefined behavior mentioned in
>>> 6.2.6.1p5 doesn't apply.

>>
>> While an unsigned char cannot contain a trap value, I believe J.2,
>> even though it is not normative, gives the clearest statement of the
>> intent:
>>
>> "The behavior is undefined in the following circumstances: ... The
>> value of an object with automatic storage duration is used while it is
>> indeterminate."

>
> Accessing an uninitialized variable of type unsigned char is (as
> of C11) undefined behavior in some circumstances, but only some.
> This result obtains by virtue of 6.3.2.1 p2, in particular the
> last sentence.
>
> Obviously, accessing an uninitialized variable is not /always/
> undefined behavior, because if it were then there would be
> no point in adding the new proviso to 6.3.2.1 p2; undoubtedly
> the committee would simply have added some non-normative text
> instead.
>


And since the question is about a pointer into a buffer being passed,
then it'd seem that there're no trap representations for the 'unsigned
char' values in that buffer, right?

This goes back to Defect Report 260, doesn't it?

http://www.open-std.org/jtc1/sc22/wg...ocs/dr_260.htm

- Shao Miller
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      12-20-2012
pete <(E-Mail Removed)> writes:

> Tim Rentsch wrote:
>>
>> Barry Schwarz <(E-Mail Removed)> writes:
>>
>> > On Fri, 14 Sep 2012 11:48:26 -0400, James Kuyper
>> > <(E-Mail Removed)> wrote:
>> >
>> >>On 09/14/2012 11:09 AM, Mark wrote:
>> >>> Hello,
>> >>>
>> >>> I have quite a generic question. Suppose we work with fwrite(), or sendto()
>> >>> (not C standard function, but I'll assume everyone knows it) or any other
>> >>> API that takes a pointer to a buffer to trasnmit. When such a buffer is
>> >>> unititialised, does it in some ways impose undefined behaviour?
>> >>
>> >>
>> >>> I'm asking this, because when such code is run under 'valgrind' it reports a
>> >>> lot about uninitiased memory or 'unaddressable values in syscalls' -- does
>> >>> it imply such will act undefined due to uninit storages used as buffers?
>> >>>
>> >>> Would appreciate the comments on it. Thanks.
>> >>
>> >>"If an object that has automatic storage duration is not initialized
>> >>explicitly, its value is indeterminate." (6.7.9p10)
>> >>
>> >>An indeterminate value is defined as "either an unspecified value or a
>> >>trap representation" (3.19.2)
>> >>
>> >>"Certain object representations need not represent a value of the object
>> >>type. If the stored value of an object has such a representation and is
>> >>read by an lvalue expression that does not have character type, the
>> >>behavior is undefined. ... Such a representation is called a trap
>> >>representation." (6.2.6.1p5)
>> >>
>> >>So far, this looks bad. However, let's go a little further:
>> >>The description of fwrite() says "... For each object, size calls are
>> >>made to the fputc function, taking the values (in order) from an array
>> >>of unsigned char exactly overlaying the object. ..." (7.21.8.2p1). In
>> >>other words, it accesses the data using only lvalues of type unsigned
>> >>char, a character type. Therefore, the undefined behavior mentioned in
>> >>6.2.6.1p5 doesn't apply.
>> >
>> > While an unsigned char cannot contain a trap value, I believe J.2,
>> > even though it is not normative, gives the clearest statement of the
>> > intent:
>> >
>> > "The behavior is undefined in the following circumstances: ... The
>> > value of an object with automatic storage duration is used while it is
>> > indeterminate."

>>
>> Accessing an uninitialized variable of type unsigned char is (as
>> of C11) undefined behavior in some circumstances, but only some.
>> This result obtains by virtue of 6.3.2.1 p2, in particular the
>> last sentence.
>>
>> Obviously, accessing an uninitialized variable is not /always/
>> undefined behavior, because if it were then there would be
>> no point in adding the new proviso to 6.3.2.1 p2; undoubtedly
>> the committee would simply have added some non-normative text
>> instead.

>
> The last statement of 6.3.2.1 p2,
> makes me think that
> if the lvalue designates an object of automatic storage duration
> that could have been declared with the register storage class
> (never had its address taken),
> and that object is uninitialized (not declared with an initializer
> and no assignment to it has been performed prior to use),
> then the program really doen't have to reserve storage for that object.


You're assuming that the compiler can tell whether that
situation will occur. Sometimes it can, but in the
general case it can't (Halting Problem, etc).
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      12-21-2012
pete <(E-Mail Removed)> writes:

> Tim Rentsch wrote:
>>
>> pete <(E-Mail Removed)> writes:
>>
>> > Tim Rentsch wrote:
>> >>
>> >> Barry Schwarz <(E-Mail Removed)> writes:
>> >>
>> >> > On Fri, 14 Sep 2012 11:48:26 -0400, James Kuyper
>> >> > <(E-Mail Removed)> wrote:
>> >> >
>> >> >>On 09/14/2012 11:09 AM, Mark wrote:
>> >> >>> Hello,
>> >> >>>
>> >> >>> I have quite a generic question. Suppose we work with fwrite(), or sendto()
>> >> >>> (not C standard function, but I'll assume everyone knows it) or any other
>> >> >>> API that takes a pointer to a buffer to trasnmit. When such a buffer is
>> >> >>> unititialised, does it in some ways impose undefined behaviour?
>> >> >>
>> >> >>
>> >> >>> I'm asking this, because when such code is run under 'valgrind' it reports a
>> >> >>> lot about uninitiased memory or 'unaddressable values in syscalls' -- does
>> >> >>> it imply such will act undefined due to uninit storages used as buffers?
>> >> >>>
>> >> >>> Would appreciate the comments on it. Thanks.
>> >> >>
>> >> >>"If an object that has automatic storage duration is not initialized
>> >> >>explicitly, its value is indeterminate." (6.7.9p10)
>> >> >>
>> >> >>An indeterminate value is defined as "either an unspecified value or a
>> >> >>trap representation" (3.19.2)
>> >> >>
>> >> >>"Certain object representations need not represent a value of the object
>> >> >>type. If the stored value of an object has such a representation and is
>> >> >>read by an lvalue expression that does not have character type, the
>> >> >>behavior is undefined. ... Such a representation is called a trap
>> >> >>representation." (6.2.6.1p5)
>> >> >>
>> >> >>So far, this looks bad. However, let's go a little further:
>> >> >>The description of fwrite() says "... For each object, size calls are
>> >> >>made to the fputc function, taking the values (in order) from an array
>> >> >>of unsigned char exactly overlaying the object. ..." (7.21.8.2p1). In
>> >> >>other words, it accesses the data using only lvalues of type unsigned
>> >> >>char, a character type. Therefore, the undefined behavior mentioned in
>> >> >>6.2.6.1p5 doesn't apply.
>> >> >
>> >> > While an unsigned char cannot contain a trap value, I believe J.2,
>> >> > even though it is not normative, gives the clearest statement of the
>> >> > intent:
>> >> >
>> >> > "The behavior is undefined in the following circumstances: ... The
>> >> > value of an object with automatic storage duration is used while it is
>> >> > indeterminate."
>> >>
>> >> Accessing an uninitialized variable of type unsigned char is (as
>> >> of C11) undefined behavior in some circumstances, but only some.
>> >> This result obtains by virtue of 6.3.2.1 p2, in particular the
>> >> last sentence.
>> >>
>> >> Obviously, accessing an uninitialized variable is not /always/
>> >> undefined behavior, because if it were then there would be
>> >> no point in adding the new proviso to 6.3.2.1 p2; undoubtedly
>> >> the committee would simply have added some non-normative text
>> >> instead.
>> >
>> > The last statement of 6.3.2.1 p2,
>> > makes me think that
>> > if the lvalue designates an object of automatic storage duration
>> > that could have been declared with the register storage class
>> > (never had its address taken),
>> > and that object is uninitialized (not declared with an initializer
>> > and no assignment to it has been performed prior to use),
>> > then the program really doen't have to reserve storage for that object.

>>
>> You're assuming that the compiler can tell whether that
>> situation will occur. Sometimes it can, but in the
>> general case it can't (Halting Problem, etc).

>
> It's the only reason that I can think of for why
>
> int main(void) {unsigned char x; return x - x;}
>
> should be undefined.


It turns out that some actual hardware has out-of-band marking
(for registers, I think) that indicate non-initialization. Those
machiness (can) trap on a reference to an unitialized register.
My understanding is that the passage we are discussing was added
specifically because such machines currently exist, and more
generally because it is useful to allow similar kinds of traps
or what-have-you, yet still be inside the boundaries of being
a conforming implementation.
 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      12-21-2012
Tim Rentsch <(E-Mail Removed)> wrote:

(snip, someone wrote)
>> It's the only reason that I can think of for why


>> int main(void) {unsigned char x; return x - x;}


>> should be undefined.


> It turns out that some actual hardware has out-of-band marking
> (for registers, I think) that indicate non-initialization. Those
> machiness (can) trap on a reference to an unitialized register.


More usual would be tagged memory, which can have an unitialized,
or otherwise trap representation.

Stories are that the original WATFOR on the 7090 used parity
errors to detect uninitialized variables. It could actually
set invalid parity before starting execution of the compiled
program.

I believe some Burroughs machines tag memory locations for their
contents. I will guess that there is a trap representation for
the tag.

Though presumable one could say that C requires that such memory
or parity bits be initialized to valid values before the program
starts executing.

> My understanding is that the passage we are discussing was added
> specifically because such machines currently exist, and more
> generally because it is useful to allow similar kinds of traps
> or what-have-you, yet still be inside the boundaries of being
> a conforming implementation.


Well, at least signaling NaN exists on modern systems.

-- glen

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
uninitialised variable but NO error geek.arnuld@gmail.com C++ 2 02-04-2007 11:05 AM
uninitialised variable but NO error geek.arnuld@gmail.com C++ 2 02-04-2007 08:19 AM
Calling free() on an uninitialised pointer? santosh C Programming 13 12-05-2005 09:05 PM
value of an uninitialised variable Andy Fish XML 7 01-10-2005 04:37 PM
C++: Uninitialised Variable Passed as a Parm Gene Wirchenko C++ 22 12-19-2003 02:26 PM



Advertisments