Saphire
Saphire

Reputation: 1930

Pointer arithmetic with NULLs

Can someone explain, why

int main(void)
{
    char *a = NULL;
    int *b = NULL;
    double *c = NULL;

    printf("\n%d %d %d\n%d %d %d\n\n",
    (int) (a+1), (int)(b+1), (int)(c+1),
    (int) (a+5), (int)(b+7), (int)(c+17));
    return 0;
}

outputs

1, 4, 8
5, 28, 136

I think it has something to do with the byte-sizes of those variables. But I don't understand the second line of output.

Upvotes: 5

Views: 1667

Answers (5)

alk
alk

Reputation: 70971

Arithmetic operations on NULL-pointers are undefined behaviour.

From the C-standard:

6.3.2.3 Pointers

[...] 3 If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

[...]

6.5.6 Additive operators

[...] 2 For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integer type.

[...]

Apx J.2 Undefined behavior

[...]

Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object (6.5.6).

Upvotes: 2

TypeIA
TypeIA

Reputation: 17258

If p is a pointer to type T, and it holds memory address X, then p + N is the memory address X + N * sizeof(T).

(int) (a +  1) == 0 +  1 * sizeof(char)   ==  1 * 1 ==   1
(int) (b +  1) == 0 +  1 * sizeof(int)    ==  1 * 4 ==   4
(int) (c +  1) == 0 +  1 * sizeof(double) ==  1 * 8 ==   8

(int) (a +  5) == 0 +  5 * sizeof(char)   ==  5 * 1 ==   5
(int) (b +  7) == 0 +  7 * sizeof(int)    ==  7 * 4 ==  28
(int) (c + 17) == 0 + 17 * sizeof(double) == 17 * 8 == 136

Minor note: As Barmar points out in his answer, arithmetic on NULL pointers is technically undefined behavior. So a standard-compliant compiler could have done something different with that arithmetic; the code might have printed 1, 3.1415, or a picture of dogs playing poker. But the behavior you observed is the same as the defined behavior you would've observed if you'd started with valid pointers, so you probably don't need to worry about this.

Upvotes: 15

R Sahu
R Sahu

Reputation: 206707

a+5 = 0 + sizeof(char)*5 = 5
b+7 = 0 + sizeof(int)*7 = 28
c+7 = 0 + sizeof(double)*17 = 136

Upvotes: 3

Barmar
Barmar

Reputation: 782107

Arithmetic on null pointers results in undefined behavior, so any result is possible.

Upvotes: 2

Nik Bougalis
Nik Bougalis

Reputation: 10613

In C, pointer arithmetic depends on the size of the underlying type.

When you do p + n on some pointer p you don't really add n to it. Instead you add n * (sizeof(*p)). That, is you advance the pointer by n items.

Upvotes: 4

Related Questions