473,406 Members | 2,217 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

checking array indices


when I define
int R[99];
and then later access it with
x=R[r];C[x]=7;
....
but x happens to be <0 or >99 , then the program's behavious
becomes unpredictable.

Is there a way to prevent this ?
Is there a program or debugger or compiler which
checks the array indices before executing the command and
eventually issues an error-warning when the index is out of range ?
Nov 14 '05 #1
26 1682
Sterten wrote:
when I define
int R[99];
and then later access it with
x=R[r];C[x]=7;
...
but x happens to be <0 or >99 , then the program's behavious
Surely you mean "but x happens to be <0 or >98"
becomes unpredictable.

Is there a way to prevent this ?


Yes. Don't write bad code that attempts to access beyond the bounds of
the array.
Nov 14 '05 #2

"Sterten" <st*****@aol.com> wrote in message news:20***************************@mb-m05.aol.com...

when I define
int R[99];
and then later access it with
x=R[r];C[x]=7;
...
but x happens to be <0 or >99 , then the program's behavious
becomes unpredictable.
You must mean x < 0 or x >= 99 in the above.

You can try this:

assert((unsigned) i < 99);
t = R[i];

Is there a way to prevent this ?
Is there a program or debugger or compiler which
checks the array indices before executing the command and
eventually issues an error-warning when the index is out of range ?

Nov 14 '05 #3
>> int R[99];
and then later access it with
x=R[r];C[x]=7;


You must mean x < 0 or x >= 99 in the above.

You can try this:

assert((unsigned) i < 99);
t = R[i];


Bare in mind that assert() is a debug tool. It helps to trap impossible
or forbidden by-design statuses. But it is not designed to trap user
level errors.

BTW, on many development systems, the assert() macro is simply ignored
at release time, due to the definition of the global NDEBUG macro.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html

"C is a sharp tool"

Nov 14 '05 #4
On Sat, 24 Jul 2004 17:26:10 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:

"Sterten" <st*****@aol.com> wrote in message news:20***************************@mb-m05.aol.com...

when I define
int R[99];
and then later access it with
x=R[r];C[x]=7;
...
but x happens to be <0 or >99 , then the program's behavious
becomes unpredictable.
You must mean x < 0 or x >= 99 in the above.

You can try this:

assert((unsigned) i < 99);


Why the cast. If i contains a sufficiently large negative value, your
assert will be true but your next statement will invoke undefined
behavior.
t = R[i];

Is there a way to prevent this ?
Is there a program or debugger or compiler which
checks the array indices before executing the command and
eventually issues an error-warning when the index is out of range ?


<<Remove the del for email>>
Nov 14 '05 #5
I'm thinking just at a program which traverses
the .c source program and includes
a line
if(xxx<0 || xxx>99)printf("index out of range in line yyy")

directly before every line yyy containing
R[xxx] , which it finds.
Then the new converted .c program
can be compiles and executed when problems with array indices are suspected.

Seems not very difficult to write such a program, someone must have done it
already ?!?

Nov 14 '05 #6
Sterten wrote on 25/07/04 :
I'm thinking just at a program which traverses
the .c source program and includes
a line
if(xxx<0 || xxx>99)printf("index out of range in line yyy")

directly before every line yyy containing
R[xxx] , which it finds.
Then the new converted .c program
can be compiles and executed when problems with array indices are suspected.

Seems not very difficult to write such a program, someone must have done it
already ?!?


Sounds to be a good idea, but it might more complicated if pointers are
involved, what happens when you 'pass an array' to a function for
example...

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html

"C is a sharp tool"

Nov 14 '05 #7
Barry Schwarz <sc******@deloz.net> writes:
On Sat, 24 Jul 2004 17:26:10 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:
"Sterten" <st*****@aol.com> wrote in message
news:20***************************@mb-m05.aol.com...

when I define
int R[99];
and then later access it with
x=R[r];C[x]=7;
...
but x happens to be <0 or >99 , then the program's behavious
becomes unpredictable.


You must mean x < 0 or x >= 99 in the above.

You can try this:

assert((unsigned) i < 99);


Why the cast. If i contains a sufficiently large negative value, your
assert will be true but your next statement will invoke undefined
behavior.
t = R[i];


No, there is no negative value of type int that yields a value less
than 99 when converted to unsigned int. (There might be exotic
representations where this isn't the case.)

But I'd still be more comfortable with

assert(i >= 0 && i < 99);

(assuming that assert is a good way to do the check in the first
place).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #8

"Keith Thompson" <ks***@mib.org> wrote in message news:ln************@nuthaus.mib.org...
Barry Schwarz <sc******@deloz.net> writes:
On Sat, 24 Jul 2004 17:26:10 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:
"Sterten" <st*****@aol.com> wrote in message
news:20***************************@mb-m05.aol.com...
>
> when I define
> int R[99];
> and then later access it with
> x=R[r];C[x]=7;
> ...
> but x happens to be <0 or >99 , then the program's behavious
> becomes unpredictable.

You must mean x < 0 or x >= 99 in the above.

You can try this:

assert((unsigned) i < 99);
Why the cast. If i contains a sufficiently large negative value, your
assert will be true but your next statement will invoke undefined
behavior.
t = R[i];


No, there is no negative value of type int that yields a value less
than 99 when converted to unsigned int. (There might be exotic
representations where this isn't the case.)


The idea that, "There might be some exotic implementation where this isn't the case," hadn't occurred to me. I can't imagine what it
would be like. Hmmm.

In any case, on two's complement machines, a good optimizing compiler will convert "i >= 0 && i < 99" to "(unsigned) i < 99", since
this saves several assembly instructions. The cast from int to unsigned consumes zero machine cycles on two's complement machines.
In an assert, this is not important, but anywhere else, this is a nice trick. I just thought I throw it into my post to make people
think.

But I'd still be more comfortable with

assert(i >= 0 && i < 99);
For an assert() or any code that is serious about being readable for that matter, your way is much better.

(assuming that assert is a good way to do the check in the first
place).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Nov 14 '05 #9
>Sterten wrote on 25/07/04 :
I'm thinking just at a program which traverses
the .c source program and includes
a line
if(xxx<0 || xxx>99)printf("index out of range in line yyy")

directly before every line yyy containing
R[xxx] , which it finds.
Then the new converted .c program
can be compiles and executed when problems with array indices are

suspected.

Seems not very difficult to write such a program, someone must have done it
already ?!?


Sounds to be a good idea, but it might more complicated if pointers are
involved, what happens when you 'pass an array' to a function for
example...

--
Emmanuel


I can see no principal difference, except
that the function-definition-line with
Array[] should be discarded of course.

hmm, what's with Array[function(x)] =whatever; ?
you'd have to do something like

y=function(x); if(y<Range1 or y>range2)printf("error");
Array[y]=whatever;
but then, this can be nested to several levels...
:-(

--Guenter.
Nov 14 '05 #10
"Ricardo Gibert" <no**********@cox.net> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...

[...]
No, there is no negative value of type int that yields a value less
than 99 when converted to unsigned int. (There might be exotic
representations where this isn't the case.)


The idea that, "There might be some exotic implementation where this
isn't the case," hadn't occurred to me. I can't imagine what it
would be like. Hmmm.


I was thinking vaguely of something involving padding bits, for
example, where INT_MAX and UINT_MAX are both 2**31-1 (perhaps because
the underlying hardware doesn't support unsigned integer arithmetic).
It's unlikely in real life, and I'm not even sure whether it would
cause the specified results.

[...]
But I'd still be more comfortable with

assert(i >= 0 && i < 99);


For an assert() or any code that is serious about being readable for
that matter, your way is much better.

(assuming that assert is a good way to do the check in the first
place).


On the other hand, if the more obscure form results in faster code,
and it actually turns out to be a bottleneck, it might make sense to
use it -- but I'd encapsulate it in a well-commented macro. (On the
other other hand, since assert() is effectively ignored if NDEBUG is
defined, optimization probably doesn't matter much anyway.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #11
On Sun, 25 Jul 2004 07:18:37 GMT, Keith Thompson <ks***@mib.org>
wrote:
Barry Schwarz <sc******@deloz.net> writes:
On Sat, 24 Jul 2004 17:26:10 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:
>"Sterten" <st*****@aol.com> wrote in message
>news:20***************************@mb-m05.aol.com...
>>
>> when I define
>> int R[99];
>> and then later access it with
>> x=R[r];C[x]=7;
>> ...
>> but x happens to be <0 or >99 , then the program's behavious
>> becomes unpredictable.
>
>You must mean x < 0 or x >= 99 in the above.
>
>You can try this:
>
> assert((unsigned) i < 99);
Why the cast. If i contains a sufficiently large negative value, your
assert will be true but your next statement will invoke undefined
behavior.
> t = R[i];


No, there is no negative value of type int that yields a value less
than 99 when converted to unsigned int. (There might be exotic
representations where this isn't the case.)


This is only true in the "common" situation where the absolute value
of INT_MIN is only half of UINT_MAX. The standard does not require
this. It is possible for these values to be equal but opposite in
sign. It would be legal on a 32-bit system for
INT_MAX=UINT_MAX=pow(2,31)-1 and INT_MIN=-INT_MAX. (There is no
requirement that an unsigned int use the now irrelevant sign bit to
extend its range of values.) In fact, any exponent value between 31
and 16 would be compliant.

On any system where INT_MIN <= -UINT_MAX, the 99 int values
between -UINT_MAX and -UINT_MAX+98 would satisfy the assert but still
invoke undefined behavior.

But I'd still be more comfortable with

assert(i >= 0 && i < 99);

(assuming that assert is a good way to do the check in the first
place).


<<Remove the del for email>>
Nov 14 '05 #12
>On the other hand, if the more obscure form results in faster code,
and it actually turns out to be a bottleneck, it might make sense to
use it -- but I'd encapsulate it in a well-commented macro. (On the
other other hand, since assert() is effectively ignored if NDEBUG is
defined, optimization probably doesn't matter much anyway.)


I don't know "assert", will have to look this up, so maybe I misunderstand the
above.

But speed is no problem in the debug-version. Later, when it runs correctly
I will remove all this checking in the final version.

Nov 14 '05 #13

"Barry Schwarz" <sc******@deloz.net> wrote in message news:ce**********@216.39.134.239@theriver.com...
On Sun, 25 Jul 2004 07:18:37 GMT, Keith Thompson <ks***@mib.org>
wrote:
Barry Schwarz <sc******@deloz.net> writes:
On Sat, 24 Jul 2004 17:26:10 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:
>"Sterten" <st*****@aol.com> wrote in message
>news:20***************************@mb-m05.aol.com...
>>
>> when I define
>> int R[99];
>> and then later access it with
>> x=R[r];C[x]=7;
>> ...
>> but x happens to be <0 or >99 , then the program's behavious
>> becomes unpredictable.
>
>You must mean x < 0 or x >= 99 in the above.
>
>You can try this:
>
> assert((unsigned) i < 99);

Why the cast. If i contains a sufficiently large negative value, your
assert will be true but your next statement will invoke undefined
behavior.

> t = R[i];
No, there is no negative value of type int that yields a value less
than 99 when converted to unsigned int. (There might be exotic
representations where this isn't the case.)


This is only true in the "common" situation where the absolute value
of INT_MIN is only half of UINT_MAX. The standard does not require
this. It is possible for these values to be equal but opposite in
sign. It would be legal on a 32-bit system for
INT_MAX=UINT_MAX=pow(2,31)-1 and INT_MIN=-INT_MAX. (There is no
requirement that an unsigned int use the now irrelevant sign bit to
extend its range of values.) In fact, any exponent value between 31
and 16 would be compliant.

On any system where INT_MIN <= -UINT_MAX, the 99 int values
between -UINT_MAX and -UINT_MAX+98 would satisfy the assert but still
invoke undefined behavior.


A cast from int or char to unsigned does not cause undefined behavior.

But I'd still be more comfortable with

assert(i >= 0 && i < 99);

(assuming that assert is a good way to do the check in the first
place).


<<Remove the del for email>>

Nov 14 '05 #14
Sterten wrote:
when I define int R[99]; and then later access it with x=R[r]; C[x]=7;
... but x happens to be < 0 or > 99,
then the program's behaviour becomes unpredictable.

Is there a way to prevent this?
Is there a program or debugger or compiler
which checks the array indices before executing the command and
eventually issues an error-warning when the index is out of range?


The GNU C compiler used to do this and some compilers still do:

http://www.cray.com/craydoc/manuals/...-50-manual.pdf

http://techpubs.sgi.com/library/tpl/...html/ch04.html

http://docs.rinet.ru/InforSmes/ch35/ch35.htm

I used Google

+"C compiler" +"check array bounds"

to search for

+"C compiler" +"check array bounds"
Nov 14 '05 #15
"Ricardo Gibert" <no**********@cox.net> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
No, there is no negative value of type int that yields a value less
than 99 when converted to unsigned int. (There might be exotic
representations where this isn't the case.)
The idea that, "There might be some exotic implementation where this
isn't the case," hadn't occurred to me. I can't imagine what it would be
like. Hmmm.


An architecture on which the least significant bit it used as the sign
of a value combined with a C compiler which coerces int values to
unsigned by clearing the sign bit or even by shifting it to one of the
value bits.

Then -3 would be represented as 00000111 and would be coerced to
unsigned as 00000110 which would be +3 but still less than 99.


In any case, on two's complement machines, a good optimizing compiler
will convert "i >= 0 && i < 99" to "(unsigned) i < 99", since this saves
several assembly instructions. The cast from int to unsigned consumes
zero machine cycles on two's complement machines. In an assert, this is
not important, but anywhere else, this is a nice trick. I just thought I
throw it into my post to make people think.
But I'd still be more comfortable with

assert(i >= 0 && i < 99);


For an assert() or any code that is serious about being readable for
that matter, your way is much better.
(assuming that assert is a good way to do the check in the first
place).

-- Keith Thompson (The_Other_Keith) ks***@mib.org
<http://www.ghoti.net/~kst> San Diego Supercomputer Center <*>
<http://users.sdsc.edu/~kst> We must do something. This is something.
Therefore, we must do this.



--
Nov 14 '05 #16
On Sun, 25 Jul 2004 10:58:40 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:

"Barry Schwarz" <sc******@deloz.net> wrote in message news:ce**********@216.39.134.239@theriver.com...
On Sun, 25 Jul 2004 07:18:37 GMT, Keith Thompson <ks***@mib.org>
wrote:
>Barry Schwarz <sc******@deloz.net> writes:
>> On Sat, 24 Jul 2004 17:26:10 -0700, "Ricardo Gibert"
>> <no**********@cox.net> wrote:
>> >"Sterten" <st*****@aol.com> wrote in message
>> >news:20***************************@mb-m05.aol.com...
>> >>
>> >> when I define
>> >> int R[99];
>> >> and then later access it with
>> >> x=R[r];C[x]=7;
>> >> ...
>> >> but x happens to be <0 or >99 , then the program's behavious
>> >> becomes unpredictable.
>> >
>> >You must mean x < 0 or x >= 99 in the above.
>> >
>> >You can try this:
>> >
>> > assert((unsigned) i < 99);
>>
>> Why the cast. If i contains a sufficiently large negative value, your
>> assert will be true but your next statement will invoke undefined
>> behavior.
>>
>> > t = R[i];
>
>No, there is no negative value of type int that yields a value less
>than 99 when converted to unsigned int. (There might be exotic
>representations where this isn't the case.)


This is only true in the "common" situation where the absolute value
of INT_MIN is only half of UINT_MAX. The standard does not require
this. It is possible for these values to be equal but opposite in
sign. It would be legal on a 32-bit system for
INT_MAX=UINT_MAX=pow(2,31)-1 and INT_MIN=-INT_MAX. (There is no
requirement that an unsigned int use the now irrelevant sign bit to
extend its range of values.) In fact, any exponent value between 31
and 16 would be compliant.

On any system where INT_MIN <= -UINT_MAX, the 99 int values
between -UINT_MAX and -UINT_MAX+98 would satisfy the assert but still
invoke undefined behavior.


A cast from int or char to unsigned does not cause undefined behavior.
>
>But I'd still be more comfortable with
>
> assert(i >= 0 && i < 99);
>
>(assuming that assert is a good way to do the check in the first
>place).


Obviously, but once the unsigned value has passed the assert, the
signed negative value is used as an array index and that does cause
undefined behavior.
<<Remove the del for email>>
Nov 14 '05 #17

"Barry Schwarz" <sc******@deloz.net> wrote in message news:ce**********@216.39.135.107@theriver.com...
On Sun, 25 Jul 2004 10:58:40 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:

"Barry Schwarz" <sc******@deloz.net> wrote in message news:ce**********@216.39.134.239@theriver.com...
On Sun, 25 Jul 2004 07:18:37 GMT, Keith Thompson <ks***@mib.org>
wrote:

>Barry Schwarz <sc******@deloz.net> writes:
>> On Sat, 24 Jul 2004 17:26:10 -0700, "Ricardo Gibert"
>> <no**********@cox.net> wrote:
>> >"Sterten" <st*****@aol.com> wrote in message
>> >news:20***************************@mb-m05.aol.com...
>> >>
>> >> when I define
>> >> int R[99];
>> >> and then later access it with
>> >> x=R[r];C[x]=7;
>> >> ...
>> >> but x happens to be <0 or >99 , then the program's behavious
>> >> becomes unpredictable.
>> >
>> >You must mean x < 0 or x >= 99 in the above.
>> >
>> >You can try this:
>> >
>> > assert((unsigned) i < 99);
>>
>> Why the cast. If i contains a sufficiently large negative value, your
>> assert will be true but your next statement will invoke undefined
>> behavior.
>>
>> > t = R[i];
>
>No, there is no negative value of type int that yields a value less
>than 99 when converted to unsigned int. (There might be exotic
>representations where this isn't the case.)

This is only true in the "common" situation where the absolute value
of INT_MIN is only half of UINT_MAX. The standard does not require
this. It is possible for these values to be equal but opposite in
sign. It would be legal on a 32-bit system for
INT_MAX=UINT_MAX=pow(2,31)-1 and INT_MIN=-INT_MAX. (There is no
requirement that an unsigned int use the now irrelevant sign bit to
extend its range of values.) In fact, any exponent value between 31
and 16 would be compliant.

On any system where INT_MIN <= -UINT_MAX, the 99 int values
between -UINT_MAX and -UINT_MAX+98 would satisfy the assert but still
invoke undefined behavior.
A cast from int or char to unsigned does not cause undefined behavior.

>
>But I'd still be more comfortable with
>
> assert(i >= 0 && i < 99);
>
>(assuming that assert is a good way to do the check in the first
>place).

Obviously, but once the unsigned value has passed the assert, the
signed negative value is used as an array index and that does cause
undefined behavior.


Okay, I see I managed to misunderstand even though it should have been clear. Sorry.

In the event that the condition "INT_MIN <= -UINT_MAX" were true, you would be correct. Something that would exhibit such undefined
behavior would be a cast from long long to unsigned long as an example, but I don't think "INT_MIN <= -UINT_MAX" is ever true, since
unsigned is guaranteed to occupy the same amount of storage as an int.


<<Remove the del for email>>

Nov 14 '05 #18
E. Robert Tisdale wrote:
Sterten wrote:
when I define
int R[99];

and then later access it with

x=R[r]; C[x]=7;
...

but x happens to be < 0 or > 99,
then the program's behaviour becomes unpredictable.

Is there a way to prevent this?
Is there a program or debugger or compiler
which checks the array indices before executing the command and
eventually issues an error-warning when the index is out of range?


The GNU C compiler used to do this and some compilers still do:

http://www.cray.com/craydoc/manuals/...-50-manual.pdf
http://techpubs.sgi.com/library/tpl/...=linux&db=bks&

srch=&fname=/SGI_Admin/Porting_Guide/sgi_html/ch04.html
http://docs.rinet.ru/InforSmes/ch35/ch35.htm
I will check these later offline.
I'm using gcc3.2 .
Although I also asked for a compiler-referrence, I think
I'd prefer a program to convert my
..c-source to another .c-program with
bounds-checking
I used Google

+"C compiler" +"check array bounds"

to search for

+"C compiler" +"check array bounds"

hmm, I had used combinations with "array indices" rather than "array bounds"
and
found a referrence to the compaq-compiler
Nov 14 '05 #19


Sterten wrote:

when I define
int R[99];
and then later access it with
x=R[r];C[x]=7;
...
but x happens to be <0 or >99 , then the program's behavious
becomes unpredictable.

Is there a way to prevent this ?
Is there a program or debugger or compiler which
checks the array indices before executing the command and
eventually issues an error-warning when the index is out of range ?


You do not show us how array C is declared. Of course, if x<0 there will
be a problem, but we can't tell about >99 unless you declare C as
C[100]. Perhaps you mean r<0 or r>98?

Using assert is fine when you are developing and testing, but unless you
can ABSOLUTELY guarantee that 0<=r<=98 and no value of R is ourside the
bounds of a legal index for C, you should probably use a run-time check:
if ( r<0 || r>98 ) ...
Also, using a magic number like '98' is not a great idea - set a macro
to that value instead.

Note also that assert() will not just generate a warning message; it
will abort the program on an error. Using an 'if' test will allow the
program to write a warning message and attempt to recover, assuming you
can figure out how to do that.

Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Common User Interface Services
M/S 2R-94 (206)544-5225
Nov 14 '05 #20
>you should probably use a run-time check:
if ( r<0 || r>98 ) ...


but there can be hundreds of array-accesses
in the program, even nested, so I prefer
a program to do this checking automatically,
like I'm used it to be in BASIC.
Nov 14 '05 #21
Giorgos Keramidas wrote:
"Ricardo Gibert" <no**********@cox.net> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
No, there is no negative value of type int that yields a value less
than 99 when converted to unsigned int. (There might be exotic
representations where this isn't the case.)


The idea that, "There might be some exotic implementation where this
isn't the case," hadn't occurred to me. I can't imagine what it would be
like. Hmmm.

An architecture on which the least significant bit it used as the sign
of a value combined with a C compiler which coerces int values to
unsigned by clearing the sign bit or even by shifting it to one of the
value bits.

Then -3 would be represented as 00000111 and would be coerced to
unsigned as 00000110 which would be +3 but still less than 99.


If this happens, the language is not C. Period.

The result of converting -3 to `unsigned int' is
`UINT_MAX - 2'. Always. And since `UINT_MAX' is at
least 65535, the result will be at least 65533 and
most definitely greater than 99.

--
Er*********@sun.com

Nov 14 '05 #22
Eric Sosman <Er*********@sun.com> writes:
Giorgos Keramidas wrote:
"Ricardo Gibert" <no**********@cox.net> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...

No, there is no negative value of type int that yields a value less
than 99 when converted to unsigned int. (There might be exotic
representations where this isn't the case.)

The idea that, "There might be some exotic implementation where this
isn't the case," hadn't occurred to me. I can't imagine what it would be
like. Hmmm.

An architecture on which the least significant bit it used as the
sign
of a value combined with a C compiler which coerces int values to
unsigned by clearing the sign bit or even by shifting it to one of the
value bits.
Then -3 would be represented as 00000111 and would be coerced to
unsigned as 00000110 which would be +3 but still less than 99.


If this happens, the language is not C. Period.

The result of converting -3 to `unsigned int' is
`UINT_MAX - 2'. Always. And since `UINT_MAX' is at
least 65535, the result will be at least 65533 and
most definitely greater than 99.


What about a machine with 24-bit words, with UINT_MAX and INT_MAX both
set to 8388607 (2**23-1)?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #23
Keith Thompson wrote:
Eric Sosman <Er*********@sun.com> writes:
Giorgos Keramidas wrote:

An architecture on which the least significant bit it used as the
sign
of a value combined with a C compiler which coerces int values to
unsigned by clearing the sign bit or even by shifting it to one of the
value bits.
Then -3 would be represented as 00000111 and would be coerced to
unsigned as 00000110 which would be +3 but still less than 99.


If this happens, the language is not C. Period.

The result of converting -3 to `unsigned int' is
`UINT_MAX - 2'. Always. And since `UINT_MAX' is at
least 65535, the result will be at least 65533 and
most definitely greater than 99.


What about a machine with 24-bit words, with UINT_MAX and INT_MAX both
set to 8388607 (2**23-1)?


What's the "what" you're concerned about? -3 would
convert to UINT_MAX - 2, as always, yielding the value
8388605 which is larger than 99 -- I'm sure that's not
what's worrying you, but I don't know what is ...

--
Er*********@sun.com

Nov 14 '05 #24
Eric Sosman <Er*********@sun.com> writes:
Keith Thompson wrote:
Eric Sosman <Er*********@sun.com> writes:
Giorgos Keramidas wrote:
An architecture on which the least significant bit it used as the
sign
of a value combined with a C compiler which coerces int values to
unsigned by clearing the sign bit or even by shifting it to one of the
value bits.
Then -3 would be represented as 00000111 and would be coerced to
unsigned as 00000110 which would be +3 but still less than 99.

If this happens, the language is not C. Period.

The result of converting -3 to `unsigned int' is
`UINT_MAX - 2'. Always. And since `UINT_MAX' is at
least 65535, the result will be at least 65533 and
most definitely greater than 99.

What about a machine with 24-bit words, with UINT_MAX and INT_MAX
both
set to 8388607 (2**23-1)?


What's the "what" you're concerned about? -3 would
convert to UINT_MAX - 2, as always, yielding the value
8388605 which is larger than 99 -- I'm sure that's not
what's worrying you, but I don't know what is ...


A few articles upthread, I wrote:

] No, there is no negative value of type int that yields a value less
] than 99 when converted to unsigned int. (There might be exotic
] representations where this isn't the case.)

If UINT_MAX and INT_MAX both have the value 8388607 (2**23-1), then
the int value -8388558, converted to unsigned int, yields the value 50.

The context was a suggestion to use something like

assert((unsigned) i <= 99);

as an optimization of

assert(i >= 0 && i <= 99);

The check would fail on the hypothetical exotic system if i is equal
to 8388607, causing undefined behavior when i is subsequently used as
an index into a 100-element array.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #25
On Sun, 25 Jul 2004 22:12:41 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:

"Barry Schwarz" <sc******@deloz.net> wrote in message news:ce**********@216.39.135.107@theriver.com...
On Sun, 25 Jul 2004 10:58:40 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:
>
>"Barry Schwarz" <sc******@deloz.net> wrote in message news:ce**********@216.39.134.239@theriver.com...
>> On Sun, 25 Jul 2004 07:18:37 GMT, Keith Thompson <ks***@mib.org>
>> wrote:
>>
>> >Barry Schwarz <sc******@deloz.net> writes:
>> >> On Sat, 24 Jul 2004 17:26:10 -0700, "Ricardo Gibert"
>> >> <no**********@cox.net> wrote:
>> >> >"Sterten" <st*****@aol.com> wrote in message
>> >> >news:20***************************@mb-m05.aol.com...
>> >> >>
>> >> >> when I define
>> >> >> int R[99];
>> >> >> and then later access it with
>> >> >> x=R[r];C[x]=7;
>> >> >> ...
>> >> >> but x happens to be <0 or >99 , then the program's behavious
>> >> >> becomes unpredictable.
>> >> >
>> >> >You must mean x < 0 or x >= 99 in the above.
>> >> >
>> >> >You can try this:
>> >> >
>> >> > assert((unsigned) i < 99);
>> >>
>> >> Why the cast. If i contains a sufficiently large negative value, your
>> >> assert will be true but your next statement will invoke undefined
>> >> behavior.
>> >>
>> >> > t = R[i];
>> >
>> >No, there is no negative value of type int that yields a value less
>> >than 99 when converted to unsigned int. (There might be exotic
>> >representations where this isn't the case.)
>>
>> This is only true in the "common" situation where the absolute value
>> of INT_MIN is only half of UINT_MAX. The standard does not require
>> this. It is possible for these values to be equal but opposite in
>> sign. It would be legal on a 32-bit system for
>> INT_MAX=UINT_MAX=pow(2,31)-1 and INT_MIN=-INT_MAX. (There is no
>> requirement that an unsigned int use the now irrelevant sign bit to
>> extend its range of values.) In fact, any exponent value between 31
>> and 16 would be compliant.
>>
>> On any system where INT_MIN <= -UINT_MAX, the 99 int values
>> between -UINT_MAX and -UINT_MAX+98 would satisfy the assert but still
>> invoke undefined behavior.
>
>A cast from int or char to unsigned does not cause undefined behavior.
>
>>
>> >
>> >But I'd still be more comfortable with
>> >
>> > assert(i >= 0 && i < 99);
>> >
>> >(assuming that assert is a good way to do the check in the first
>> >place).
>>
>>
>>

Obviously, but once the unsigned value has passed the assert, the
signed negative value is used as an array index and that does cause
undefined behavior.


Okay, I see I managed to misunderstand even though it should have been clear. Sorry.

In the event that the condition "INT_MIN <= -UINT_MAX" were true, you would be correct. Something that would exhibit such undefined
behavior would be a cast from long long to unsigned long as an example, but I don't think "INT_MIN <= -UINT_MAX" is ever true, since
unsigned is guaranteed to occupy the same amount of storage as an int.


But there is no requirement that an unsigned int use the sign bit to
extend its range. It is legal for INT_MIN to be -(pow(2,31)-1) and
UINT_MAX and INT_MAX both to be pow(2,31)-1.
<<Remove the del for email>>
Nov 14 '05 #26

"Barry Schwarz" <sc******@deloz.net> wrote in message
news:ce**********@216.39.134.211@theriver.com...
On Sun, 25 Jul 2004 22:12:41 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:

"Barry Schwarz" <sc******@deloz.net> wrote in message news:ce**********@216.39.135.107@theriver.com...
On Sun, 25 Jul 2004 10:58:40 -0700, "Ricardo Gibert"
<no**********@cox.net> wrote:

>
>"Barry Schwarz" <sc******@deloz.net> wrote in message news:ce**********@216.39.134.239@theriver.com... >> On Sun, 25 Jul 2004 07:18:37 GMT, Keith Thompson <ks***@mib.org>
>> wrote:
>>
>> >Barry Schwarz <sc******@deloz.net> writes:
>> >> On Sat, 24 Jul 2004 17:26:10 -0700, "Ricardo Gibert"
>> >> <no**********@cox.net> wrote:
>> >> >"Sterten" <st*****@aol.com> wrote in message
>> >> >news:20***************************@mb-m05.aol.com...
>> >> >>
>> >> >> when I define
>> >> >> int R[99];
>> >> >> and then later access it with
>> >> >> x=R[r];C[x]=7;
>> >> >> ...
>> >> >> but x happens to be <0 or >99 , then the program's behavious
>> >> >> becomes unpredictable.
>> >> >
>> >> >You must mean x < 0 or x >= 99 in the above.
>> >> >
>> >> >You can try this:
>> >> >
>> >> > assert((unsigned) i < 99);
>> >>
>> >> Why the cast. If i contains a sufficiently large negative value, your >> >> assert will be true but your next statement will invoke undefined
>> >> behavior.
>> >>
>> >> > t = R[i];
>> >
>> >No, there is no negative value of type int that yields a value less
>> >than 99 when converted to unsigned int. (There might be exotic
>> >representations where this isn't the case.)
>>
>> This is only true in the "common" situation where the absolute value
>> of INT_MIN is only half of UINT_MAX. The standard does not require
>> this. It is possible for these values to be equal but opposite in
>> sign. It would be legal on a 32-bit system for
>> INT_MAX=UINT_MAX=pow(2,31)-1 and INT_MIN=-INT_MAX. (There is no
>> requirement that an unsigned int use the now irrelevant sign bit to
>> extend its range of values.) In fact, any exponent value between 31
>> and 16 would be compliant.
>>
>> On any system where INT_MIN <= -UINT_MAX, the 99 int values
>> between -UINT_MAX and -UINT_MAX+98 would satisfy the assert but still
>> invoke undefined behavior.
>
>A cast from int or char to unsigned does not cause undefined behavior.
>
>>
>> >
>> >But I'd still be more comfortable with
>> >
>> > assert(i >= 0 && i < 99);
>> >
>> >(assuming that assert is a good way to do the check in the first
>> >place).
>>
>>
>>
Obviously, but once the unsigned value has passed the assert, the
signed negative value is used as an array index and that does cause
undefined behavior.
Okay, I see I managed to misunderstand even though it should have been clear. Sorry.
In the event that the condition "INT_MIN <= -UINT_MAX" were true, you would be correct. Something that would exhibit such undefinedbehavior would be a cast from long long to unsigned long as an example, but I don't think "INT_MIN <= -UINT_MAX" is ever true, sinceunsigned is guaranteed to occupy the same amount of storage as an int.


But there is no requirement that an unsigned int use the sign bit to
extend its range. It is legal for INT_MIN to be -(pow(2,31)-1) and
UINT_MAX and INT_MAX both to be pow(2,31)-1.


I see that I have no choice, but to accept this as a legal possibility. I can't
find anything in the standard that precludes this. Strictly speaking, it seems
the trick is a technical error portability-wise, though useful to the compiler
writer or assembly language programmer.

Thanks for being patient with me.


<<Remove the del for email>>

Nov 14 '05 #27

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Steve | last post by:
I'm working on an e-commerce site, and one of the things I need to do is split an existing order into two orders. The problem I'm having is not creating the new order, but getting the remaining...
6
by: Michael Drumheller | last post by:
(If you're not interested in NumArray, please skip this message.) I am new to NumArray and I wonder if someone can help me with array-indexing. Here's the basic situation: Given a rank-2 array...
11
by: Dr John Stockton | last post by:
Q1 : Given an array such as might have been generated by var A = is there a highly effective way of reducing it to - i.e. removing the undefineds and shifting the rest down? ...
9
by: Randell D. | last post by:
Folks, I can program fairly comfortably in PHP and can, for the most part using these skills and others that I've picked up over the years manage to read/understand most code in Javascript... so...
7
by: Adam Hartshorne | last post by:
As a result of a graphics based algorihtms, I have a list of indices to a set of nodes. I want to efficiently identify any node indices that are stored multiple times in the array and the...
22
by: VK | last post by:
A while ago I proposed to update info in the group FAQ section, but I dropped the discussion using the approach "No matter what color the cat is as long as it still hounts the mice". Over the last...
29
by: shmartonak | last post by:
For maximum portability what should the type of an array index be? Can any integer type be used safely? Or should I only use an unsigned type? Or what? If I'm using pointers to access array...
9
by: dennis.sam | last post by:
Hi, Is there away to define a multi-dimensional array with respect to the number of dimensions the array has? For example, given a user spec of "a b c d", I want to create a 4 dimensional array...
11
by: memeticvirus | last post by:
I have an array cli::array<float, 2and I would like to access a subset of it's values by compiling an array of pointers. But, it's not possible to create an array of type...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.