trap representation

P

pemo

Ambiguous?

I have a student who's asked me to explain the following std text (esp. the
footnote).

6.2.6.1.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 read 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.41) Such a
representation is called a trap representation.

Footnote

41) Thus, an automatic variable can be initialized to a trap representation
without causing undefined behavior, but the value of the variable cannot be
used until a proper value is stored in it.

On hearing him explain what he *thought* it meant, I've come to the
conclusion that the standard's either badly worded, or else I've been using
an incorrect term when I teach.

For example, I've gone to great pains to draw a distinction between
initialization vs. assignment - int i = 10, as opposed to int i; i = 10;
However, I also realize that I've *said* that autos are *initialized* with
unknown values, or garbage. Nevertheless, I must have said the latter a lot
less than the former - as the student certainly read 'programmer specified
initialization' for 'an automatic variable can be initialized' into the
sense of the footnote's text.

Let me paraphrase footnote 41 with the substance of what they were saying:

41) Thus, an automatic variable can be *explicitly initialized* to a trap
representation without causing undefined behavior, but the value of the
variable cannot be used until a proper value is stored in it.

I.e., the student thought that a *trap representation* was something
useful - I guess they were thinking of it as a kind of guard mechanism, that
could somehow benefit them.

Once explained, they were quite happy, but it's made me think that I ought
not to use the word initialized when talking about autos, or else that the
footnote should perhaps be reworded to something like:

* Thus, an automatic variable can be initialized by the implementation to a
trap representation .

* Thus, an automatic variable can be set to a trap representation by the
implementation .

* Thus, an automatic variable can be covertly initialized to a trap
representation .

* Thus, an automatic variable's value can be initialized to any arbitrary
value, it can be initialized to a trap representation .

Or some better wording?

BTW, is it just me, and do others object to 'can' where 'may' is more
semantically accurate [and 'better' English]?
 
P

pete

pemo said:
Ambiguous?

I have a student who's asked me to explain the following std text (esp. the
footnote).

6.2.6.1.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 read 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.41) Such a
representation is called a trap representation.

Footnote

41) Thus, an automatic variable can be initialized to a trap representation
without causing undefined behavior, but the value of the variable cannot be
used until a proper value is stored in it.

On hearing him explain what he *thought* it meant, I've come to the
conclusion that the standard's either badly worded, or else I've been using
an incorrect term when I teach.

For example, I've gone to great pains to draw a distinction between
initialization vs. assignment -
int i = 10, as opposed to int i; i = 10;

The syntax is different
Initialization allows but does not require an rvalue.
int i = {10};
is valid.
i = {10};
is not valid.

An uninitialized object may or may not contain a trap representation.
Defining an uninitialized object is insufficient
to cause undefined behavior.
Accessing the value of an uninitialized object
is what gives undefined behavior.

int i;
is valid.

int i;
i = i;
is undefined.
 
P

pemo

pete said:
The syntax is different
Initialization allows but does not require an rvalue.
int i = {10};
is valid.
i = {10};
is not valid.

An uninitialized object may or may not contain a trap representation.
Defining an uninitialized object is insufficient
to cause undefined behavior.
Accessing the value of an uninitialized object
is what gives undefined behavior.

int i;
is valid.

int i;
i = i;
is undefined.

Um, [I think] I know all this, the question was to do with the wording, not
what its means.
 
M

Mark McIntyre

Ambiguous?

I don't think so. But then I have the benefit of a couple of decades
of C programming. :)
41) Thus, an automatic variable can be initialized to a trap representation
without causing undefined behavior, but the value of the variable cannot be
used until a proper value is stored in it.

I believe its not ambiguous because the meaning your students put on
it is impossible. You can't read a trap value other than as unsigned
chars. So how could you initialise a variable with a trap value, since
to do so, you have to read that trap value?
BTW, is it just me, and do others object to 'can' where 'may' is more
semantically accurate [and 'better' English]?

In 'better' English the two have different meanings. 'may' strictly
implies 'has permission to' whereas 'can' implies 'is able to'.

"may I jump over the wall?" -> do I have permission to,,,
"Can he jump that high?" -> is he able to....
 
T

Thad Smith

pemo said:
Ambiguous?

I have a student who's asked me to explain the following std text (esp. the
footnote).

6.2.6.1.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 read 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.41) Such a
representation is called a trap representation.

Footnote

41) Thus, an automatic variable can be initialized to a trap representation
without causing undefined behavior, but the value of the variable cannot be
used until a proper value is stored in it.

On hearing him explain what he *thought* it meant, I've come to the
conclusion that the standard's either badly worded, or else I've been using
an incorrect term when I teach.

For example, I've gone to great pains to draw a distinction between
initialization vs. assignment - int i = 10, as opposed to int i; i = 10;
However, I also realize that I've *said* that autos are *initialized* with
unknown values, or garbage.

Your choice of words is unfortunate. "Initialized," in C, means given
an explicit value in a declaration. This applies to either static or
automatic variables. In the absence of such explicit value, automatic
variables are uninitialized and may contain any "unknown values", as you
say, including trap representations for the declared type.

Nevertheless, I must have said the latter a lot
less than the former - as the student certainly read 'programmer specified
initialization' for 'an automatic variable can be initialized' into the
sense of the footnote's text.

Let me paraphrase footnote 41 with the substance of what they were saying:

41) Thus, an automatic variable can be *explicitly initialized* to a trap
representation without causing undefined behavior, but the value of the
variable cannot be used until a proper value is stored in it.

I.e., the student thought that a *trap representation* was something
useful - I guess they were thinking of it as a kind of guard mechanism, that
could somehow benefit them.

It is possible for an implementation to provide a default value of auto
variables which contain a trap representation, for debugging purposes,
but most implementations don't and it is not guaranteed. There is no
way to explicitly initialize a variable with a trap representation,
since initialization stores a value of the indicated type and trap
representations are not values for the type.
Once explained, they were quite happy, but it's made me think that I ought
not to use the word initialized when talking about autos, or else that the
footnote should perhaps be reworded to something like:

Yes, it would be better to be consistent with the wording of the
standard w.r.t. terms like initialization.
* Thus, an automatic variable can be initialized by the implementation to a
trap representation .

That would not be initialization.
* Thus, an automatic variable can be set to a trap representation by the
implementation .

It could be, as mentioned above. More typically, the trap
representation is something left over from prior use, which was not a
variable of the same type.
* Thus, an automatic variable can be covertly initialized to a trap
representation .

That sounds intriguing, but would be misleading.
* Thus, an automatic variable's value can be initialized to any arbitrary
value, it can be initialized to a trap representation .

I would say that the storage associated with an uninitialized variable
can contain an arbitrary bit pattern, usually from prior use, which may
be a trap representation for the variable's type.
 
B

Ben Pfaff

pemo said:
41) Thus, an automatic variable can be initialized to a trap representation
without causing undefined behavior, but the value of the variable cannot be
used until a proper value is stored in it.

To me, besides the obvious, this brings the following to mind:

int a;
foo(a);

I'm not certain whether that's undefined behavior or not, but the
footnote suggests that it may not be.
 
C

Christopher Benson-Manica

Ben Pfaff said:
To me, besides the obvious, this brings the following to mind:
int a;
foo(a);
I'm not certain whether that's undefined behavior or not, but the
footnote suggests that it may not be.

Quoth Jack Klein in another thread...

"Assignment in C is always based on value, so passing anything with
indeterminate value, other than an unsigned char, to a function is
undefined behavior, as is any other use of the value of such an
object. It makes no difference whether the object with indeterminate
value is part of a structure, nor does it make any difference how the
value became indeterminate."
 
J

Jack Klein

Ambiguous?

I have a student who's asked me to explain the following std text (esp. the
footnote).

6.2.6.1.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 read 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.41) Such a
representation is called a trap representation.

Footnote

41) Thus, an automatic variable can be initialized to a trap representation
without causing undefined behavior, but the value of the variable cannot be
used until a proper value is stored in it.

On hearing him explain what he *thought* it meant, I've come to the
conclusion that the standard's either badly worded, or else I've been using
an incorrect term when I teach.

For example, I've gone to great pains to draw a distinction between
initialization vs. assignment - int i = 10, as opposed to int i; i = 10;
However, I also realize that I've *said* that autos are *initialized* with
unknown values, or garbage. Nevertheless, I must have said the latter a lot
less than the former - as the student certainly read 'programmer specified
initialization' for 'an automatic variable can be initialized' into the
sense of the footnote's text.

Let me paraphrase footnote 41 with the substance of what they were saying:

41) Thus, an automatic variable can be *explicitly initialized* to a trap
representation without causing undefined behavior, but the value of the
variable cannot be used until a proper value is stored in it.

I.e., the student thought that a *trap representation* was something
useful - I guess they were thinking of it as a kind of guard mechanism, that
could somehow benefit them.

Once explained, they were quite happy, but it's made me think that I ought
not to use the word initialized when talking about autos, or else that the
footnote should perhaps be reworded to something like:

* Thus, an automatic variable can be initialized by the implementation to a
trap representation .

* Thus, an automatic variable can be set to a trap representation by the
implementation .

* Thus, an automatic variable can be covertly initialized to a trap
representation .

* Thus, an automatic variable's value can be initialized to any arbitrary
value, it can be initialized to a trap representation .

Or some better wording?

BTW, is it just me, and do others object to 'can' where 'may' is more
semantically accurate [and 'better' English]?

I think all four of your suggestions suffer from the same problem that
the original wording has, namely the use of the word "initialization"
which has a specific meaning in the standard, and is here used in a
different context.

I think the use of the word "initialization" in the footnote is
unfortunate and a mistake. I think we can define a term that does not
exist in the standard, and give it a meaning that we can all agree on.
Try this on for size:

"initial value" is the value of an object defined without an
initializer between its definition and the assignment of a value to
it.

OK so far?

Now we have three types storage duration in C, static, automatic, and
allocated. We'll leave automatic for last because the other two types
are clearer.

The "initial value" for any object with static storage duration,
remember that "initial value" only applies to objects defined without
an initializer, is 0, 0.0, and NULL, for integer types, floating point
types, and pointers, or for these respective types if they are part of
an aggregate object. No controversy here.

Allocated objects contain 'random' bit patterns when allocated via
malloc() or realloc(), 'random' in the sense that they are unknown or
unconstrained. This is one of the causes of what the standard calls
an "indeterminate value". I'm talking new allocations with realloc(),
not actually reallocating. We'll leave calloc() out of the picture.

So the "initial value" of newly allocated memory obtained from
malloc() or realloc() is 'random', and depending on the object type
used to access this memory, may be an invalid representation otherwise
known as a "trap representation". I hope there is no problem here.

Now we come to automatic objects. Just like memory newly obtained
from malloc() or realloc(), the C standard places no requirements on
its initial contents. Unlike static objects, there is no default
initialization, so it could contain any combination of bits. Just as
in the case of allocated memory, the "initial value" is 'random' or
indeterminate. For objects types that have trap representations, this
pattern of bits just might happen to be one.

If you try to access the "initial value" of an automatic or allocated
object prior to storing a valid value of the object type into the
object, you will access the 'random' or 'indeterminate' "initial
value", and it just might be a trap representation for the object
type.

I think the wording of the footnote would have been more correct and
less confusing had it been something like this:

"Thus, an automatic variable has an initial indeterminate value that
might be a trap representation for the type, which does not cause
undefined behavior, but the value of the variable cannot be
used until a proper value is stored in it."

Interestingly, N869, the last public draft of C99 before it was
ratified, had this definition for undefined behavior:

"behavior, upon use of a nonportable or erroneous program construct,
of erroneous data, or of indeterminately valued objects, for which
this International Standard imposes no requirements"

This was specifically changed in the final standard to:

"behavior, upon use of a nonportable or erroneous program construct or
of erroneous data, for which this International Standard imposes no
requirements"

Note that use of an object with indeterminate value was eliminated.
The reason for this is the exception given to accessing any object,
initialized or not, indeterminate or not, as an array of unsigned
chars, which have no trap representations and thus no undefined
behavior.
 
M

Michael Wojcik

Your choice of words is unfortunate. "Initialized," in C, means given
an explicit value in a declaration.

Except, apparently, in 6.2.6.1.5 note 41, which uses "initialized" to
mean "the value that results when no explicit value was given in a
declaration". Which, I believe, was pemo's point.

Footnotes are not normative (a term which has specific meaning in ISO
standards, and it's not "of no consequence whatsoever"), but they are
nonetheless part of the text of the standard.

Thus it would be more accurate to say that "initialized" *usually*
means "given an explicit value in a declaration" - but the standard
is not entirely consistent in that usage.
That would not be initialization.

It's still an improvement on the existing wording.
It could be, as mentioned above. More typically, the trap
representation is something left over from prior use, which was not a
variable of the same type.

That's still "set ... by the implementation". It doesn't matter
whether the implementation expressly sets it to a trap representation
(or any other value) or simply allows it to take on such a value over
the course of the program's execution; from the program's point of
view, it's still the result of the implementation's behavior.

It's also beside the point, which is the misleading wording of this
footnote in the standard.

I think introducing "covertly" to the standard, as a term with
technical meaning that is not currently used (much less defined) in
the text, is the wrong way to go.

This is a comma splice (two independent clauses joined with only a
comma), which is awkward (and wrong, if you're a prescriptivist).
And this still suffers from the discrepant use of "initialized".

Better wording might be something like:

41) Thus, an automatic variable without an explicit initializer can
initially contain a trap representation without causing undefined
behavior, but the value of the variable cannot be used until a proper
value is stored in it.

--
Michael Wojcik (e-mail address removed)

Q: What is the derivation and meaning of the name Erwin?
A: It is English from the Anglo-Saxon and means Tariff Act of 1909.
-- Columbus (Ohio) Citizen
 
T

Tim Rentsch

pemo said:
Ambiguous?

I have a student who's asked me to explain the following std text (esp. the
footnote).

6.2.6.1.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 read 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.41) Such a
representation is called a trap representation.

Footnote

41) Thus, an automatic variable can be initialized to a trap representation
without causing undefined behavior, but the value of the variable cannot be
used until a proper value is stored in it.

On hearing him explain what he *thought* it meant, I've come to the
conclusion that the standard's either badly worded, or else I've been using
an incorrect term when I teach.

For example, I've gone to great pains to draw a distinction between
initialization vs. assignment - int i = 10, as opposed to int i; i = 10;
However, I also realize that I've *said* that autos are *initialized* with
unknown values, or garbage. Nevertheless, I must have said the latter a lot
less than the former - as the student certainly read 'programmer specified
initialization' for 'an automatic variable can be initialized' into the
sense of the footnote's text.

Let me paraphrase footnote 41 with the substance of what they were saying:

41) Thus, an automatic variable can be *explicitly initialized* to a trap
representation without causing undefined behavior, but the value of the
variable cannot be used until a proper value is stored in it.

I.e., the student thought that a *trap representation* was something
useful - I guess they were thinking of it as a kind of guard mechanism, that
could somehow benefit them.

Once explained, they were quite happy, but it's made me think that I ought
not to use the word initialized when talking about autos, or else that the
footnote should perhaps be reworded to something like: [several possible
rewordings snipped]

The question you're asking isn't so much about what the Standard says as
how to reconcile, or to explain to the students, how it says it. If it
were me, I would try an explanation like this:

"The Standard defines the term _initializer_ but doesn't actually give
definitions for initialize, initialized, initialization, or initial
value. Usually these terms are used in a way that is more or less
synonymous with what happens when using an _initializer_, but the
Standard doesn't precisely insist on this point. The wording in
the footnote is probably meant to point out that a conforming
program can arrange for an object to be set to a particular trap
representation without transgressing on undefined behavior. This
setting can be accomplished with, eg, 'memcpy()'."

The footnote might reasonably be reworded thusly:

41) Thus, an automatic variable can be given a specific trap
representation value, before any other accesses, without
causing undefined behavior; but the value of the variable
cannot be used (without possibly causing a trap) until a
proper value is stored in it.

I don't find it confusing to use the word "initialized" in the sense
of "given a specific initial value, by whatever means", nor
contradictory to how the Standard uses the terms; but I've
specifically avoided the phrase "initial value" in the footnote
rewording above.

Incidentally, it is possible using an initializer to give an object a
specific initial value that's a trap representation (ie, without UB).
See if you can figure out a way to do that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top