Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do C standards specify how far the carry propagates when incrementing a pointer?

Consider the following situations:

  • The National Semiconductor SC/MP has pointers which, when you keep incrementing them, will roll from 0x0FFF to 0x0000 because the increment circuit does not propagate the carry past the lower nybble of the higher byte. So if, for example, I want to do while(*ptr++) to traverse a null-terminated string, then I might wind up with ptr pointing outside of the array.

  • On the PDP-10, because a machine word is longer than an address1, a pointer may have tags and other data in the upper half of the word containing the address. In this situation, if incrementing a pointer causes an overflow, that other data might get altered. The same goes for very early Macintoshes, before the ROMs were 32-bit clean.

So my question is about whether the C standard says what incrementing a pointer really means. As far as I can tell, the C standard assumes that it should work in bit-wise the same manner as incrementing an integer. But that doesn't always hold, as we have seen.

Can a standards-conforming C compiler emit a simple adda a0, 12 to increment a pointer, without checking that the presence or lack of carry propagation will not lead to weirdness?


1: On the PDP-10, an address is 18 bits wide, but a machine word is 36 bits wide. A machine word may hold either two pointers (handy for Lisp) or one pointer, plus bitfields which mean things like "add another level of indirection", segments, offsets etc. Or a machine word may of course contain no pointers, but that's not relevant to this question.

2: Add one to an address. That's 68000 assembler.

like image 314
OmarL Avatar asked Aug 14 '18 19:08

OmarL


People also ask

How do you increment a pointer structure?

When a pointer is incremented, it actually increments by the number equal to the size of the data type for which it is a pointer. For Example: If an integer pointer that stores address 1000 is incremented, then it will increment by 2(size of an int) and the new address it will points to 1002.

What happens when you add to a pointer in C?

Pointer Arithmetic Unlike regular numbers, adding 1 to a pointer will increment its value (a memory address) by the size of its underlying data type. To simplify the logic behind this, think of pointer arithmetic the same way you think about array indexing.


1 Answers

Behavior of pointer arithmetic is specified by the C standard only as long as the result points to a valid object or just past a valid object. More than that, the standard does not say what the bits of a pointer look like; an implementation may arrange them to suit its own purposes.

So, no, the standard does not say what happens when a pointer is incremented so far that the address rolls over.

If the while loop you refer to only proceeds one element past the end of the array, it is safe in C. (Per the standard, if ptr has been incremented to one element beyond the end of the array, and x points to any element in the array, including the first, then x < ptr must be true. So, if ptr has rolled over internally, the C implementation is responsible for ensuring the comparison still works.)

If your while loop may increment ptr more than one element beyond the end of the array, the C standard does not define the behavior.

like image 62
Eric Postpischil Avatar answered Oct 23 '22 10:10

Eric Postpischil