In C++ language you can't just do
int Array[][100]; /* ERROR: incomplete type */
because that would be a definition of an object of incomplete type, which is explicitly illegal in C++. You can use that in a non-defining declaration
extern int Array[][100];
(or as a static member of a class), but when it will come to the actual definition of the same array object both sizes will have to be specified explicitly (or derived from an explicit initializer).
In C the situation is not much different, except that in C there are such things as tentative definitions which let you write
int Array[][100];
However, a tentative definition in this regard is pretty similar to a non-defining declaration, which is why it is allowed. Eventually you will have to define the same object with explicitly specified size in the same translation unit (some compilers don't require that as an non-stanard extension). If you try something like that in a non-tentative definition, you'll get an error
static int Array[][100]; /* ERROR: incomplete type */
So, if you think of it, aside from tentative definitions, the situation in C and C++ is not much different: it is illegal to define objects of incomplete type in these languages and an array of unspecified size is an incomplete type.