0

I'm in a data structures course, our midterm is coming up and our practice midterm asks if each line is valid syntax:

int num = 10;
int *p, *q;
p = #

q = p;  //valid
*p = q; //invalid, int* cannot be assigned to int
(*p)++; //valid
&num+1; //valid ********
p++;    //valid ********

So the last two lines of code, as I understand it, add 1 to the address of the num variable.

What purpose would this have in coding?

melpomene
  • 84,125
  • 8
  • 85
  • 148
Skathix
  • 278
  • 1
  • 3
  • 14

2 Answers2

3

In this case, that would lead to undefined behavior. It would address the int that follows num in memory, but there is no defined way to tell what that would be. Nonetheless, it is valid syntax.

It would make a great deal more sense if your pointer pointed to an element of an array instead of a scalar. In that case, addressing the next int is reasonable. But in both cases the syntax is valid.

Logicrat
  • 4,438
  • 16
  • 22
  • 1
    If my understanding is correct, setting your pointer to one-past-the-end of your memory is not undefined, though referencing it is. In this case, he doesn't reference the pointer after setting it to one-past-the-end in either line, so he should be fine. – R_Kapp Oct 16 '15 at 21:19
  • 1
    @R_Kapp: And there's a special rule making an object equivalent to an array with one element, so that the "one-past-the-end-of-the-array" rule applies also to a pointer to a scalar object, like this. – Ben Voigt Oct 16 '15 at 21:20
  • That is an astute observation. However, I recently got into trouble doing exactly what I think you are describing, when I ported some code from one machine to another After some head-scratching, I found out that the new machine didn't align scalars to the same specs as the older machine. But you're right; simply taking the address of one past an int is not UB, but dereferencing it can be. – Logicrat Oct 16 '15 at 21:25
0

A purpose this would have in coding is to write tests such as:

void f ( size_t length, int data[length] )
{
  assert( 0 == length % 4 );
  for ( int* p = data; p < data + length; p += 4 )
    do_stuff_with_subarray( p, 4 );

  return;
}

The loop condition p < data + length bounds-checks the pointer by comparing it to the address one past the end of the array. Dereferencing this address would be undefined behavior, but comparing to it is not. (In this simplistic example, though, there will be UB if do_stuff_with_subarray() ever reads past the end of an array whose length is not divisible by 4.)

Davislor
  • 14,674
  • 2
  • 34
  • 49