"the value stored in that space--the value of the variable--isn't
defined. It might be zero, or it might be some random "garbage" value"
That sounds right, I always declare and initialize variables anyway
(before using them - otherwise they're pointless).
But it did make me think about what is contained in the variable (or
from the computer's view - the area in memory) before it's
initialized. If there is a value in that memory area then it
presumably gets overwritten or moved when you initialize the variable.
/*The good thing about learning C (unlike, say most VB books and
tutorials) is that you also think away from the language and into the
machine.*/
I did some experiments with showing the contents uninitialized
variables and pointers to them and it is a bit strange, some values,
some apparent nonsense / nothingness, some error producing stuff.
What's going on in there? Is it really just "garbage"?
Thanks
Sent via Deja.com
http://www.deja.com/
Consider memory to be reusable, so what is in there is whatever there
had been in there before you started to put something in there ...
> The good thing about learning C (unlike, say most VB books and
> tutorials) is that you also think away from the language and into the
> machine.
I tend to do that also, but please be very careful with what you say
about platform/machine dependent issues in this group ;-)
willem
> Some things about reading through C books hits me, stuff like:
>
> "the value stored in that space--the value of the variable--isn't
> defined. It might be zero, or it might be some random "garbage" value"
>
> That sounds right, I always declare and initialize variables anyway
> (before using them - otherwise they're pointless).
>
> But it did make me think about what is contained in the variable (or
> from the computer's view - the area in memory) before it's
> initialized.
Garbage. _Nothing_ predictable from the ISO Standard.
> If there is a value in that memory area then it
> presumably gets overwritten or moved when you initialize the variable.
Overwritten, of course; where would you move garbage to?
> /*The good thing about learning C (unlike, say most VB books and
> tutorials) is that you also think away from the language and into the
> machine.*/
Au contraire. When you _really_ learn C, you'll learn that the language
is everything; the machine may be transmogrified into a DS9K tomorrow,
but ISO C stays the same and will still work.
> I did some experiments with showing the contents uninitialized
> variables and pointers to them and it is a bit strange, some values,
> some apparent nonsense / nothingness, some error producing stuff.
>
> What's going on in there? Is it really just "garbage"?
Yes. Some debugging compilers (or debuggers) may choose to initialise
memory with a specific pattern (0xDEADBEEF is a famous one), but you
cannot in any way rely on this. The standard does not even specify that
uninitialised variables may not contain trap values.
Richard
> gswork wrote:
> >
> > But it did make me think about what is contained in the variable (or
> > from the computer's view - the area in memory) before it's
> > initialized. If there is a value in that memory area then it
> > presumably gets overwritten or moved when you initialize the variable.
>
> Consider memory to be reusable, so what is in there is whatever there
> had been in there before you started to put something in there ...
No, not even that. It _might_ be. It might not be. It may be
pre-initialised to specific garbage; it might contain the inherited
garbage from whatever you ran before this program; it might contain
quantum-uncertain garbage until you force it to contain something
specific. _Nothing_ can be said about the garbage without specifying
something beyond ISO C.
Richard
I fail to see the conflict with my statement. Garbage is garbage as far
as I'm concerned, who- or whatever put that garbage in there, and even
if that garbage is sheer poetry on its own ...
void *mymalloc(size_t size)
{
char *poem = {"Denkend aan Holland zie ik brede rivieren"
"traag door oneindig laagland gaan"
"Rijen oneindig ijle populieren"
"Als hoge pluimen aan den einder staan"};
if ((buf = malloc(size)) != NULL)
memcpy(buf, poem, MIN(size, strlen(poem));
return(buf);
}
And it's even portable guys (at least I hope so ;-)
willem
<snipped>
>
> I did some experiments with showing the contents uninitialized
> variables and pointers to them and it is a bit strange, some values,
> some apparent nonsense / nothingness, some error producing stuff.
>
> What's going on in there? Is it really just "garbage"?
>
have a look at the C-faq Question 1.30
http://www.eskimo.com/~scs/C-faq/q1.30.html
Since an uninitialised automatic variable contains garbage (anything),
it can be a value which appears perfectly acceptable when it is read -
but you can't assume that it will always contain a reasonable value.
On the 32 bit machine I use, ints must be aligned on a 4 byte boundary.
If I have an uninitialised pointer to an int, it is very likely that the
value held by this variable will equate to a memory location not owned
by the application and I'll get a Segmentation Fault. Should it, by
fluke, be an addressable location there is still a strong possibility
that it will not satisfy the alignment requirement and I'll get a Bus
Error. Even if it appears to work, there is no guarantee next time I
run the application that it will behave the same.
Hope that helps.
I don't always initialise every variable when I declare it, but I do try
and keep my functions small so that variables tend to be declared where
they are used. I find this makes it easier to see whether variables are
being used uninitialised.
Hopefully your compiler has a switch to allow it to report possible use
of uninitialised variables.
Des Walker
Alenia-Marconi Systems
> Overwritten, of course; where would you move garbage to?
The moment I posted the message I realized the computer wouldnt mess
about moving memory contents around it wasnt asked too (it would have
to write over something else anyway!). Should've caught this before I
sent it.
> > /*The good thing about learning C (unlike, say most VB books and
> > tutorials) is that you also think away from the language and into
the
> > machine.*/
>
> Au contraire. When you _really_ learn C, you'll learn that the
language
> is everything; the machine may be transmogrified into a DS9K tomorrow,
> but ISO C stays the same and will still work.
I really meant thinking about how computers work with memory allocating
and addressing rather than specific machines, but point taken.
The 'programming culture' around VB doesnt really ask the learner to
think about these things.
thanks
The C standard calls this an ``indeterminately valued'' object,
rather than calling it an undefined value, or garbage.
>That sounds right, I always declare and initialize variables anyway
>(before using them - otherwise they're pointless).
Sometimes it doesn't make sense to intialize a variable, because its
first use in the code assigns a value to it. Blindly initializing all
variables may prevent certain debugging tools from doing their job. A
tool, perhaps built into the compiler, which detects uses of
uninitialized variables will not complain if a variable is given
an initial value. However, the correct fix for an uninitialized
variable, isn't necessarily to give that variable some initial value;
it could be that the entire logic is wrong. A variable must have the
correct initial value to make the algorithm work for all valid inputs!
>But it did make me think about what is contained in the variable (or
>from the computer's view - the area in memory) before it's
>initialized. If there is a value in that memory area then it
>presumably gets overwritten or moved when you initialize the variable.
>
>/*The good thing about learning C (unlike, say most VB books and
>tutorials) is that you also think away from the language and into the
>machine.*/
This is actually a bad thing, because there is no ``the'' machine. If
you think too much into your machine, you end up learnign C as a high
level assembler rather than as an abstract programming language.
You are already stepping into that by pondering about the contents of
indeterminately valued objects. The document which defines the C
language says nothing about the contents, only that accessing an
indeterminately valued object results in undefined behavior.
This means that a conforming implementation of the C language can have
a mechanism for diagnosing uses of indeterminate objects.
>I did some experiments with showing the contents uninitialized
>variables and pointers to them and it is a bit strange, some values,
>some apparent nonsense / nothingness, some error producing stuff.
>
>What's going on in there? Is it really just "garbage"?
What's going on is that the variables are bound to some locations
in memory. That memory always has some state from the moment you turn
your computer on. When a computer is powered up, the memory may contain
zeros, or random garbage. Moreover, memory is reused among programs
and among parts of the same program. If you use a memory location
without storing a value into it first, then you get the bits that came
up when the machine was powered up, or some bits that were used
previously for something else.
Not portable, won't compile, null-terminator not copied (unless that was
your intention)
By saying that there is garbage in an indeterminately-valued object,
you are saying that there is something in it, which is more than what
the standard says.
A C implementation can diagnose uses of indeterminate objects, rather
than permit access to some old data that is there.
>void *mymalloc(size_t size)
>{
>char *poem = {"Denkend aan Holland zie ik brede rivieren"
> "traag door oneindig laagland gaan"
> "Rijen oneindig ijle populieren"
> "Als hoge pluimen aan den einder staan"};
>
> if ((buf = malloc(size)) != NULL)
> memcpy(buf, poem, MIN(size, strlen(poem));
So now the buffer contains the characters of the poem, which may safely
be retrieved by the caller. That is very different from an
indeterminate value.
>And it's even portable guys (at least I hope so ;-)
And as such it fails to demonstrate the concept of an indeterminate
value, whose use is rarely, if ever, portable.
Usenet? The Web?
> Sometimes it doesn't make sense to intialize a variable, because its
> first use in the code assigns a value to it. Blindly initializing all
> variables may prevent certain debugging tools from doing their job. A
> tool, perhaps built into the compiler, which detects uses of
> uninitialized variables will not complain if a variable is given
> an initial value. However, the correct fix for an uninitialized
> variable, isn't necessarily to give that variable some initial value;
> it could be that the entire logic is wrong. A variable must have the
> correct initial value to make the algorithm work for all valid inputs!
Good advice, though by 'always' I did mean before I used the variable
(to do some operation) rather than initializing for the fun of it.
> >/*The good thing about learning C (unlike, say most VB books and
> >tutorials) is that you also think away from the language and into the
> >machine.*/
>
> This is actually a bad thing, because there is no ``the'' machine. If
> you think too much into your machine, you end up learnign C as a high
> level assembler rather than as an abstract programming language.
A lot of people see it as a semi-HLL though, we had a discussion over
it just before christmas (critique of C, pointers etc - it think the
thread was). I think I am appealed to by this because I would like to
understand 'the machine' better rather than because it's good to do so
per-se.
Basing that on the philosophy that the more you understand about the
computer the better you can program it (in any language)
Indeed, managing memory in C, with Malloc and pointers etc (unlike say
BASIC) is pretty abstract stuff for someone not raised on computer
science. I'm not convinced it inhibits abstract programming
creativity. HLLs in which you don't have to do much memory managing
are often touted for their faster development times, thinking of VB. I
don't think they automatically lend themselves to greater scope for
creativity.
I pondered about the contents of indeterminates because texts I had
read say are "don't let it happen" rather than what is going on when
you leave a variable indeterminate. So it intrigued me.
> What's going on is that the variables are bound to some locations
> in memory. That memory always has some state from the moment you turn
> your computer on. When a computer is powered up, the memory may
contain
> zeros, or random garbage. Moreover, memory is reused among programs
> and among parts of the same program. If you use a memory location
> without storing a value into it first, then you get the bits that came
> up when the machine was powered up, or some bits that were used
> previously for something else.
Thanks for that. With all the responses it's clicked in my mind and
I'm glad I asked.
You must be joking... Does the standard actually say that there can not
be something in it, because then you would know what is in there?
> A C implementation can diagnose uses of indeterminate objects, rather
> than permit access to some old data that is there.
Do you mean that this intederminatly-valued object is reserved for
debuggers and other god-given tools, or is it also for us mortals
allowed to use this value for whatever we like as intermediate object,
for instance a poem?
[snip poem]
> So now the buffer contains the characters of the poem, which may
> safely be retrieved by the caller. That is very different from an
> indeterminate value.
It wasn't intended to be retrieved by the caller. I just like poetry.
So I was not even supposed to do that? I often zero out memory on
allocation because it saves a lot of work, e.g. with a matrix, but that
is obviously a highly illegal practice too?
> >And it's even portable guys (at least I hope so ;-)
>
> And as such it fails to demonstrate the concept of an indeterminate
> value, whose use is rarely, if ever, portable.
I think I will have a look for an other language ...
Huh? You do something because you want to do it, not because
it's a good thing to do? (That's what I understood from your
sentence above.)
> Basing that on the philosophy that the more you understand
> about the computer the better you can program it (in any
> language)
It is a wrong philosophy, precisely as Kaz said. There is no
"the computer"! Computers come and go.
This is not to say that expertise on a single computer is a
bad thing. It's expertise on a single computer without
appreciation of other computers that's a bad thing.
There is no "the language" either, btw. Knowing, for example,
only C can blind you to a solution that is far better
expressed using another language.
[...]
> I pondered about the contents of indeterminates because texts I had
> read say are "don't let it happen" rather than what is going on when
> you leave a variable indeterminate. So it intrigued me.
This is a case in point. Imagine if you had a secure operating
system that writes zeroes to memory allocated to a program
(the previously program that used the memory might have stored a
credit card number that your program can steal). Armed with this
knowledge, you might mistakenly assume that uninitialized variables
contain zeroes. Because you understand your local floating point
format, you might assume that an uninitialized float or double
thus contains 0.0.
If you appreciated that not all operating systems would zero out
your memory and not all FP formats represent 0.0 as all bits
zero, then you become a better programmer.
It says that you cannot know what is in there by saying that using an
indeterminately valued object constitutes undefined behavior. Therefore
a strictly conforming program simply cannot do that. The value of the
object is imponderable.
The term indeterminate means nothing in itself; it's just a semantic
place holder which connects uninitialized values with undefined
behavior. One place in the standard says that uninitialized objects
have an indeterminate value. Another place says that using an
indeterminately valued object results in undefined behavior. The
common term brings these together to create meaning.
The term ``garbage values'' or for that matter ``purple values'' could
be used instead, but that's not the word that was selected.
If you use a different word, then you are talking about some other
language, not standard C. The term ``garbage'', if not accompanied by
a precise definition that states otherwise, suggests a value that can
safely be used (for example in a context where a pseudo-random value is
acceptable). Whereas indeterminate values cannot safely be used.
>> A C implementation can diagnose uses of indeterminate objects, rather
>> than permit access to some old data that is there.
>
>Do you mean that this intederminatly-valued object is reserved for
>debuggers and other god-given tools, or is it also for us mortals
>allowed to use this value for whatever we like as intermediate object,
>for instance a poem?
You cannot use an indeterminately valued object; the behavior is
undefined. Once you store a poem into an object, then it no longer has
an indeterminate value.
The term ``use'' means to convert an lvalue expression designating the
object to the value stored in that object---to evaluate the object.
Storing a value in an object is not considered use, because it is not
converted to its stored value.
A lot of people drink untreated water, too. :) It is true that the
basic data types and operations in C are cleraly geared toward
straightfoward implementation on conventional computers.
>it just before christmas (critique of C, pointers etc - it think the
>thread was). I think I am appealed to by this because I would like to
>understand 'the machine' better rather than because it's good to do so
>per-se.
If you want to know machines better, then study machine
architectures! There is no shortage of good text on that.
E.g. _Computer Architecture: A Quantitative Approach_ by Hennessy,
Goldberg and Patterson.
I don't believe that you can fully understand computer architecture
through C programming despite the apparent synergy between the two. It
rather works the other way around; understand architecture gives you an
intuition for writing efficient programs that make good use of a
computer's resources.
Then who or what is allowed to initialize those indeterminate values?
willem
> Kaz Kylheku wrote:
> >
> > You cannot use an indeterminately valued object; the behavior is
> > undefined. Once you store a poem into an object, then it no longer has
> > an indeterminate value.
>
> Then who or what is allowed to initialize those indeterminate values?
Storing a value in an object, whether indeterminately valued or
not, does not use its value, so it is not a problem.
--
"Large amounts of money tend to quench any scruples I might be having."
-- Stephan Wilms
I imagine he was asking a slightly different question, along
the lines of "If there exists a value so poisonous that anyone
who touches it drops dead instantly, what agency could possibly
have planted such a thing in the first place?"
The language's answer is that the implementation is allowed
(in fact, required) to perform some operations which are beyond
the ken of portable C programs -- in other words, the poisonous
values are created by magic.
A practical answer is that the question of whether a given
arrangement of bits is poisonous depends not only on the pattern,
but on how the pattern is interpreted. For example, a bunch of
bits which would be perfectly all right if viewed as a `long'
might constitute a signalling NaN if viewed as a `double'.
But it need not even be that simple. An implementation I
once used (not of C, but that's not important) deliberately used
oddball machine instructions intended for diagnostic purposes to
pre-load uninitialized variables with bad memory parity; this
caused a trap if the program subsequently read the variable
before storing it, no matter what type the variable happened to be.
In any event, there are Things We Are Not Meant To Know,
and many of these things exist inside the implementation. Some
may see this as denying programmers their rightful control over
every detail of the machine; others see it as a useful abstraction.
If you want assembly language, you know where to find it.
> If you want to know machines better, then study machine
> architectures! There is no shortage of good text on that.
> E.g. _Computer Architecture: A Quantitative Approach_ by Hennessy,
> Goldberg and Patterson.
Thanks for the book tip.
> I don't believe that you can fully understand computer architecture
> through C programming despite the apparent synergy between the two.
It
> rather works the other way around; understand architecture gives you
an
> intuition for writing efficient programs that make good use of a
> computer's resources.
>
I guess that's what I would be after and I agree that C is not the best
route to this understanding, but it definately provokes more thought
about how computers work, and requires more know-how about them than,
say, VB.
> Kaz Kylheku wrote:
> >
> > willem veenhoven wrote:
> > >
> > >I fail to see the conflict with my statement. Garbage is garbage as
> > >far as I'm concerned, who- or whatever put that garbage in there,
> > >and even if that garbage is sheer poetry on its own ...
> >
> > By saying that there is garbage in an indeterminately-valued object,
> > you are saying that there is something in it, which is more than what
> > the standard says.
>
> You must be joking... Does the standard actually say that there can not
> be something in it, because then you would know what is in there?
No, the Standard says that there is no safe way to tell whether there is
something readable in newly-allocated memory. There may be, there may
not be, but any attempt to find out what it contains or does not contain
is allowed to crash your computer - except through using unsigned char,
but there's no way of predicting from that whether the bytes in the
memory constitute values of any other type.
> > A C implementation can diagnose uses of indeterminate objects, rather
> > than permit access to some old data that is there.
>
> Do you mean that this intederminatly-valued object is reserved for
> debuggers and other god-given tools
Yes and no. Debuggers (and compilers!) are generally not pure ISO C
programs, and so can use whatever platform-specific tricks are
necessary. But they needn't always; your compiler can just request a
block of memory from the OS and leave whatever was in there in place.
>, or is it also for us mortals
> allowed to use this value for whatever we like as intermediate object,
> for instance a poem?
You're not even allowed to assume that there is any value. All you're
allowed to assume is that there is memory, which must be initialised
before being read.
> > So now the buffer contains the characters of the poem, which may
> > safely be retrieved by the caller. That is very different from an
> > indeterminate value.
>
> It wasn't intended to be retrieved by the caller. I just like poetry.
> So I was not even supposed to do that?
It makes no difference; the garbage that might have been in the memory
when you allocated it isn't there any more. You have now initialised the
memory; therefore, it isn't uninitialised any more; therefore, it does
not have indeterminate contents any more.
> > >And it's even portable guys (at least I hope so ;-)
> >
> > And as such it fails to demonstrate the concept of an indeterminate
> > value, whose use is rarely, if ever, portable.
Never, of course.
> I think I will have a look for an other language ...
If you want Pascal, you know where to find it.
Richard
> In article <3a5473e5....@news.worldonline.nl>,
> in...@hoekstra-uitgeverij.nl (Richard Bos) wrote:
>
> > > /*The good thing about learning C (unlike, say most VB books and
> > > tutorials) is that you also think away from the language and into
> > > the machine.*/
> >
> > Au contraire. When you _really_ learn C, you'll learn that the language
> > is everything; the machine may be transmogrified into a DS9K tomorrow,
> > but ISO C stays the same and will still work.
>
> I really meant thinking about how computers work with memory allocating
> and addressing rather than specific machines, but point taken.
The problem with that is that there is no such thing as "how computers
work with memory". ISO C teaches you that; proprietary languages don't.
> The 'programming culture' around VB doesnt really ask the learner to
> think about these things.
No; it expects them to silently assume that all the world's a Losedows
box, and all computers behave like a Pentium. C, OTOH, doesn't require
you to assume very much about how this particular computer works.
Richard
In article <2001Jan5.1...@lorelei.approve.se>
Goran Larsson <h...@invalid.invalid> writes:
>"except through using unsigned char"? Why do you give a simple unsigned
>char the magic ability to read indeterminately-valued objects?
It is not Richard Bos who gives out this magic ability, but rather
the C standard.
As for why, well, comp.std.c is a better place to ask, but the answer
probably works out to: "because we committee members thought it was
best." :-) (NB: I am not one of those committee members and am just
guessing.)
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc
El Cerrito, CA, USA Domain: to...@bsdi.com +1 510 234 3167
http://claw.bsdi.com/torek/ (not always up) I report spam to abuse@.
> In article <3a55a24d...@news.worldonline.nl>,
> Richard Bos <in...@hoekstra-uitgeverij.nl> wrote:
>
> > No, the Standard says that there is no safe way to tell whether there is
> > something readable in newly-allocated memory. There may be, there may
> > not be, but any attempt to find out what it contains or does not contain
> > is allowed to crash your computer - except through using unsigned char,
>
> "except through using unsigned char"? Why do you give a simple unsigned
> char the magic ability to read indeterminately-valued objects?
Reading C99: An indeterminate value is either an unspecified
value (which is not a trap representation) or a trap
representation. Access to a trap representation through a lvalue
expression of character type is explicitly allowed by 6.2.6.1,
or, rather, explicitly not made undefined. But signed char (and
char, if it is the same) can have trap representations of its own
if I am not mistaken, so unsigned char is a safer choice.
> Doesn't this make implementations that initialize indeterminately-valued
> objects to have a "hardware parity error" non conforming unless they add
> special code to handle unsigned char?
Yes.
--
"I should killfile you where you stand, worthless human." --Kaz
In other words, there hasn't been granted a complete license to access
anything through unsigned char. Only those indeterminate values that
are trap representations may be so accessed. An uninitialized value is
not known to be a trap representation, and thus cannot be accessed
in any manner. Thus a C implementation can implement a mechanism that
traps any access whatsoever to a piece of uninitialized storage. I
believe that the Purify software does something like this.
Is there anything stopping an implementation from returning a pointer
from malloc() which does not point to any physical memory until a
write to that memory is attempted? (Sort of like they way some Unix
systems' vfork() system call causes the new process to point to the
same memory as the old process until a write is done.) If so, then
even an unsigned char cannot be used to read the memory, as it does
not exist yet.
--
+---------+----------------------------------+-----------------------------+
| Kenneth | kenb...@bestweb.net | "The opinions expressed |
| J. | | herein are not necessarily |
| Brody | http://www.bestweb.net/~kenbrody | those of fP Technologies." |
+---------+----------------------------------+-----------------------------+
GCS (ver 3.12) d- s+++: a C++$(+++) ULAVHSC^++++$ P+>+++ L+(++) E-(---)
W++ N+ o+ K(---) w@ M@ V- PS++(+) PE@ Y+ PGP-(+) t+ R@ tv+() b+
DI+(++++) D---() G e* h---- r+++ y?
> In other words, there hasn't been granted a complete license to access
> anything through unsigned char. Only those indeterminate values that
> are trap representations may be so accessed. An uninitialized value is
> not known to be a trap representation, and thus cannot be accessed
> in any manner. Thus a C implementation can implement a mechanism that
> traps any access whatsoever to a piece of uninitialized storage. I
> believe that the Purify software does something like this.
n869, 6.2.6.1:
# [#4] Values stored in objects of any other object type
# consist of nĂ—CHAR_BIT bits, where n is the size of an object
# of that type, in bytes. The value may be copied into an
# object of type unsigned char [n] (e.g., by memcpy); the
# resulting set of bytes is called the object representation
# of the value. Two values (other than NaNs) with the same
# object representation compare equal, but values that compare
# equal may have different object representations.
#
# [#5] 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 accessed by an lvalue
# expression that does not have character type, the behavior
# is undefined. If such a representation is produced by a
# side effect that modifies all or any part of the object by
# an lvalue expression that does not have character type, the
# behavior is undefined.37) Such a representation is called a
# trap representation.
So if the uninitialised data is a valid value, it may be copied to an
array of unsigned char (and therefore also read directly as unsigned
char); if it is a trap value, behaviour is undefined _unless_ read as
character. And AFAICT no other values are allowed except trap and valid
ones.
Richard