Subtracting 0 from one-past-end pointer

O

Old Wolf

For the following code:

int main(void)
{
short a[100], *ptr;

ptr = a + 100;
ptr -= 0;
}

a runtime bounds-checker I use gives an error "Pointer
underrun" on the ptr -= 0 line. Is there something wrong
with that statement?
 
E

E. Robert Tisdale

Old said:
For the following code:

int main(void)
{
short a[100], *ptr;

ptr = a + 100;
ptr -= 0;
}

a runtime bounds-checker I use
gives an error "Pointer underrun" on the ptr -= 0 line.
Is there something wrong with that statement?
> cat main.c
int main(int argc, char* argv[]) {
short a[100], *ptr = a + 100;
ptr -= 0;
return 0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c
> ./main

It works fine for me.

Your run time bounds checker is probably buggy.
 
B

Ben Pfaff

int main(void)
{
short a[100], *ptr;

ptr = a + 100;
ptr -= 0;
}

a runtime bounds-checker I use gives an error "Pointer
underrun" on the ptr -= 0 line. Is there something wrong
with that statement?

No, not as far as I can tell. (I'm surprised that the compiler
emits any code for that statement though.)
 
E

E. Robert Tisdale

Ben said:
Old said:
int main(void)
{
short a[100], *ptr;

ptr = a + 100;
ptr -= 0;
}

a runtime bounds-checker I use
gives an error "Pointer underrun" on the ptr -= 0 line.
Is there something wrong with that statement?

No, not as far as I can tell.
(I'm surprised that
the compiler emits any code for that statement though.)
> cat main.c
int main(int argc, char* argv[]) {
short a[100], *ptr = a + 100;
ptr -= 0;
return 0;
}
> gcc -Wall -std=c99 -pedantic -S main.c
> cat main.sold
.file "main.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $232, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
leal -216(%ebp), %eax// a
addl $200, %eax // a + 100;
movl %eax, -220(%ebp)// ptr = a + 100
movl $0, %eax // return 0;
leave
ret
.size main, .-main
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.4.1"

My compiler doesn't.
 
R

Robert Gamble

For the following code:

int main(void)
{
short a[100], *ptr;

ptr = a + 100;
ptr -= 0;
}

a runtime bounds-checker I use gives an error "Pointer
underrun" on the ptr -= 0 line. Is there something wrong
with that statement?

I don't see anything wrong with any part of the code.

Perhaps for some reason your bounds-checker does not like the statement
before the one in question where you assign ptr to point to one past the
last element of a. Do you experience the same error if you change it to
"ptr = a + 99"?

Rob Gamble
 
R

Robert Gamble

Old said:
For the following code:

int main(void)
{
short a[100], *ptr;

ptr = a + 100;
ptr -= 0;
}

a runtime bounds-checker I use
gives an error "Pointer underrun" on the ptr -= 0 line.
Is there something wrong with that statement?
cat main.c
int main(int argc, char* argv[]) {
short a[100], *ptr = a + 100;
ptr -= 0;
return 0;
}
gcc -Wall -std=c99 -pedantic -o main main.c
./main

It works fine for me.

Your run time bounds checker is probably buggy.

$ cat test7.c
int main(void)
{
short a[100], *ptr;

ptr = a + 1000;
ptr -= 0;
}

$ gcc -Wall --std=c99 -pedantic test7.c
$ ./a.out

Works fine for me.

The point here of course being that just because your compiler didn't
produce any warnings, or even that the resulting program does not crash,
does not imply that the code exhibits no undefined behavior.

Rob Gamble
 
D

Dave Vandervies

For the following code:

int main(void)
{
short a[100], *ptr;

ptr = a + 100;
ptr -= 0;
}

a runtime bounds-checker I use gives an error "Pointer
underrun" on the ptr -= 0 line. Is there something wrong
with that statement?

I don't see anything wrong with any part of the code.

Nor do I. One past the end of an array is a valid pointer for any use
other than dereferencing it, and adding or subtracting 0 to/from a valid
pointer should be a no-op (and, in particular, give you back a (the same)
valid pointer).

Perhaps for some reason your bounds-checker does not like the statement
before the one in question where you assign ptr to point to one past the
last element of a. Do you experience the same error if you change it to
"ptr = a + 99"?

If that's the case, then the bounds-checker is wrong. It should only
trap if the OP's code tries to dereference ptr, not if it subtracts a
nonnegative value from it. (Well, nonnegative and not greater than 100.)


dave
 
D

Dan Pop

In said:
For the following code:

int main(void)
{
short a[100], *ptr;

ptr = a + 100;
ptr -= 0;
}

a runtime bounds-checker I use gives an error "Pointer
underrun" on the ptr -= 0 line. Is there something wrong
with that statement?

Nope, the standard explicitly allows it:

If both the pointer operand and the result point to elements
of the same array object, or one past the last element of the
array object, the evaluation shall not produce an overflow;

The definition of C makes *reliable* bound checking at run time incredibly
difficult, but your case can be trivially handled by a run time bound
checker.

Dan
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top