Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array declared as int v[100] but &(v[100]) gives no warning

I've the following program:

#include <stdio.h>

int main() {

    int v[100];
    int *p;

    for (p = &(v[0]); p != &(v[100]); ++p)
        if ((*p = getchar()) == EOF) {
            --p;
            break;
        }

    while (p != v)
        putchar(*--p);

    return 0;
}

And this is the output of gcc --version on the terminal:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
Thread model: posix

Why getting the address of the element after the last of an array gives me no warning but getting for example the address of v[101] gives me the following warning

test.c:8:29: warning: array index 101 is past the end of the array (which
      contains 100 elements) [-Warray-bounds]
    for(p = &(v[0]); p != &(v[101]); ++p)
                            ^ ~~~
test.c:5:5: note: array 'v' declared here
    int v[100];
    ^
1 warning generated.

I know that indexing elements out of the bounds of a buffer is undefined behaviour, so why isn't the compiler complaining about the first case?

like image 435
nbro Avatar asked Mar 12 '16 14:03

nbro


1 Answers

Moving pointer to one past the last element of array is allowed unless you dereference the pointer, so your program is valid if one or more characters are read before hitting EOF.

N1256 6.5.2.1 Array subscripting

The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).

N1256 6.5.3.2 Address and indirection operators

If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator.

N1256 6.5.6 Additive operators

Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object

like image 125
MikeCAT Avatar answered Oct 12 '22 07:10

MikeCAT