For C++ this is covered in the draft C++ standard section 3.3.2 Point of declaration:
The point of declaration for a name is immediately after its complete
  declarator (Clause 8) and before its initializer (if any), except as
  noted below. [ Example:
int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value.
  —end example ]
and:
[ Note: a name from an outer scope remains visible up to the point of
  declaration of the name that hides it.[ Example:
const int i = 2;
{ int i[i]; }
declares a block-scope array of two integers. —end example ] —end note
  ]
So in your case:
int x[x];
The const int x is visible until the closing ]. To refer to const int x after that point you can use a qualified identifer:
::x
Of course this begs the question, why not just use different names and not have to deal with these edge cases?
C
The equivalent quotes form the draft C99 standard would be from section 6.2.1 Scopes of identifiers (emphasis mine):
Structure, union, and enumeration tags have scope that begins just
  after the appearance of the tag in a type specifier that declares the
  tag. Each enumeration constant has scope that begins just after the
  appearance of its defining enumerator in an enumerator list. Any
  other identifier has scope that begins just after the completion of
  its declarator.
and:
[...] Within the inner scope, the identifier designates the entity
  declared in the inner scope; the entity declared in the outer scope is
  hidden (and not visible) within the inner scope.
there is no way to make the x in the outer scope visible in C.