Invalid values for integers

  • Thread starter Tomás Ó hÉilidhe
  • Start date
T

Tomás Ó hÉilidhe

I've heard of things called "trap values". From what I understand, if
you set an integer variable to a trap value, then the program crashes.
Is this right?

From what I understand, it seems that unsigned integers shouldn't
have any trap values seeing as how every bit-pattern is a unique number.
Also, from what I understand, the only time you could have a "trap
value" is where you're working with a sign-magnitude machine and the
machine doesn't like negative 0. Presumably, on such a machine, the
following would crash:

int i, j;

i = 0;

i |= 0x800;

j = i; /* Crashes because we've got a trap pattern */

Do I understand this alright? Are there any other trap values?

Also, what happens when you set padding bits within integers. For
instance, let's day we have a machine where:

CHAR_BIT == 8
sizeof(int) == 6 (4 bytes for value, 2 bytes of padding)

On this machine, is it OK to do the following:

unsigned i, j;

memset(&i,0x3f,sizeof(int));

j = i;

Can this cause a crash? If so, what kind of crash is it? Do we call this
a "trap value" also?
 
B

Ben Bacarisse

Tomás Ó hÉilidhe said:
I've heard of things called "trap values". From what I understand, if
you set an integer variable to a trap value, then the program crashes.
Is this right?

The behaviour is undefined and a crash is one possibility. Other
types can have trap representations (pointers being the most common).
Structs (and unions) can't (although the fields within may). This
allows assignment of structs when you don't know what is in them.

Technically, the problem is caused by accessing[1] an lvalue that has a
trap representation. Doing this:

int x;

may, in some sense, set x to a trap representation but all will be
well unless we access x before properly setting it.
From what I understand, it seems that unsigned integers shouldn't
have any trap values seeing as how every bit-pattern is a unique
number.

No. There may be padding bits in any unsigned type except unsigned
char and some combinations of padding bits may be trap
representations. You can tell, though, by examining UINT_MAX,
CHAR_BIT and sizeof(unsigned int).
Also, from what I understand, the only time you could have a "trap
value" is where you're working with a sign-magnitude machine and the
machine doesn't like negative 0.

Alas, no. After listing the three possible signed representations, we
read: "[It] is implementation-defined, [...] whether the value with
sign bit 1 and all value bits zero (for the first two), or with sign
bit and all value bits 1 (for ones’ complement), is a trap
representation or a normal value."

Presumably, on such a machine, the
following would crash:

int i, j;

i = 0;

i |= 0x800;

j = i; /* Crashes because we've got a trap pattern */

Do I understand this alright? Are there any other trap values?

Also, what happens when you set padding bits within integers. For
instance, let's day we have a machine where:

CHAR_BIT == 8
sizeof(int) == 6 (4 bytes for value, 2 bytes of padding)

On this machine, is it OK to do the following:

unsigned i, j;

memset(&i,0x3f,sizeof(int));

This is OK.
j = i;

Can this cause a crash?

It may do. The memset won't cause a problem, but just accessing i
afterwards might do.
If so, what kind of crash is it? Do we call this a "trap value"
also?

Even if the example generates a trap representation, you may not get a
"crash", though some kind of signal is probably the most common
behaviour.

[1] and certain modifications. For example, if p is a pointer, p++
could be UB because the pointer written into p is a trap rep even
though the value (the old contents) is fine.
 
R

Richard Bos

=?iso-8859-1?q?Tom=E1s_=D3_h=C9ilidhe?= said:
I've heard of things called "trap values". From what I understand, if
you set an integer variable to a trap value, then the program crashes.
Is this right?

Not quite. It causes undefined behaviour, which means that it _may_
crash. Or raise a signal, or ignore the occurrance, or anything else.
Do I understand this alright? Are there any other trap values?

AFAICT, there aren't any in integers; but floating point types have more
room for trap values.
Also, what happens when you set padding bits within integers. For
instance, let's day we have a machine where:
Can this cause a crash?

It can cause UB. Note that a recent TC has (IIRC) outlawed padding bits
within normal unsigned ints, and someone will now undoubtedly remind me
whether it also does so for signed ones.
If so, what kind of crash is it? Do we call this a "trap value" also?

We call it undefined behaviour; the Standard does not distinguish
between various kinds of undefined behaviour, and they're all equally
undefined.

Richard
 
B

Ben Bacarisse

Not quite. It causes undefined behaviour, which means that it _may_
crash. Or raise a signal, or ignore the occurrance, or anything else.


AFAICT, there aren't any in integers; but floating point types have more
room for trap values.



It can cause UB.
Note that a recent TC has (IIRC) outlawed padding bits
within normal unsigned ints, and someone will now undoubtedly remind me
whether it also does so for signed ones.

Well, I can't do that (because I don't know), but from my reading of
n1256.pdf (which I though had all the TCs merged) both signed and
unsigned ints can have trap representations made up from some
combinations of padding bits (a parity bit is given as an example).
They can't result from normal arithmetic (except from overflow in a
signed int) on normal values, but you could make one using memset as
shown.

You say the example is UB, but what causes the UB if unsigned int
can't have padding bits?
 
C

CBFalconer

Tomás Ó hÉilidhe said:
I've heard of things called "trap values". From what I understand,
if you set an integer variable to a trap value, then the program
crashes. Is this right?

No. You can't set an int to a trap value, when accessing it as an
int (barring illegal operations). If such values exist they have
to be set by the system, or possibly by accessing the object as a
series of bytes (which have no trap values).
 
K

Keith Thompson

Tomás Ó hÉilidhe said:
I've heard of things called "trap values". From what I understand, if
you set an integer variable to a trap value, then the program crashes.
Is this right?
[...]

I think your question has already been answered, but there's at least
one point nobody has explicitly raised.

They're not called "trap values", they're called "trap
representations". The whole point is that a trap representation
*doesn't* represent a value of the type.

Nothing in the C standard requires a program to "crash" (unless you
consider the result of calling abort() to be a crash). All the stuff
that you might expect to cause a crash (signed or floating-point
numeric overflow, access beyond an array, dereferencing a null or
invalid pointer, etc.) merely invokes undefined behavior. If you're
*lucky*, these things will cause your program to crash so you can find
the problem. If you're unlucky, your program will continue merrily
executing with bad data. The standard guarantees nothing.
 
B

Ben Bacarisse

Keith Thompson said:
Tomás Ó hÉilidhe said:
I've heard of things called "trap values". From what I understand, if
you set an integer variable to a trap value, then the program crashes.
Is this right?
[...]

I think your question has already been answered,

But not, unambiguously!
 
B

Ben Bacarisse

CBFalconer said:
No. You can't set an int to a trap value, when accessing it as an
int (barring illegal operations). If such values exist they have
to be set by the system, or possibly by accessing the object as a
series of bytes (which have no trap values).

"by the system" is a bit vague. They can be the result of bit-wise
operations on signed values (always a worry, but probably outside of
your category "illegal") but not, I think, from any such operation on
unsigned integer values.
 
N

Nick Keighley

   I've heard of things called "trap values". From what I understand, if
you set an integer variable to a trap value, then the program crashes.
Is this right?

   From what I understand, it seems that unsigned integers shouldn't
have any trap values seeing as how every bit-pattern is a unique number.
Also, from what I understand, the only time you could have a "trap
value" is where you're working with a sign-magnitude machine and the
machine doesn't like negative 0. Presumably, on such a machine, the
following would crash:

1's complement also gives you a -0 (negative zero)
and I've used a machine that used this to trap uninitialised
values (not with a C compiler though)


<snip>
 
C

CBFalconer

Nick said:
1's complement also gives you a -0 (negative zero)
and I've used a machine that used this to trap uninitialised
values (not with a C compiler though)

1's complement never generates a -0 IF the arithmetic is performed
with a subtractor AND addition is performed by "complement and
subtract". With a little care you can have a C compiler system
that traps all uninitialized values.
 
D

David Thompson

It can cause UB. Note that a recent TC has (IIRC) outlawed padding bits
within normal unsigned ints, and someone will now undoubtedly remind me
whether it also does so for signed ones.
YDNRC; you may have conflated some related things.

TC2 changed 6.2.6.2 to require that all-zero-bits is a valid
representation of value zero in all integer types (signed and
unsigned, and plain char which formally is neither). Thus IF there are
padding bits in an integer type, it must be valid to have padding = 0
when magnitude+sign_if_any = 0.

TC2 also changed 7.18.1.1p3 about the conditions which require the
implemention to define int{8,16,32,64}_t so they match (in fact
repeat) the requirements for those typedefs in p1 and p2.

C99 6.2.6.2p1 required that unsigned char have no padding bits, with
no such requirement on any other type, and this hasn't changed. Though
IF the implementation chooses to make plain char like unsigned char,
that must use the same representation and thus have no padding bits.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 

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,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top