a[-1] and a-1 result in undefined behavior.  First, lets get a definition for array subscripting from the C11 standard section 6.5.2.1p2:
A  postfix  expression  followed  by  an  expression  in  square  brackets
  []
  is  a  subscripted
  designation of an element of an array object.  The definition of the subscript operator
  []
  is that
  E1[E2]
  is identical to
  (*((E1)+(E2)))
  . 
So array subscripting follows the rules of pointer arithmetic when adding an integer to a pointer.
In defining pointer arithmetic in section 6.5.6p8, it sets some rules and behavior in place (emphasis mine):
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; otherwise, the
  behavior is undefined.  If the result points one past the last element of the array object, it
  shall not be used as the operand of a unary
  *
  operator that is evaluated.
The result of the pointer arithmetic involved in the array subscripting in your question is outside of the array object, therefore it results in undefined behavior.