When the second one works, it's pure chance. The fact that it ever works proves that, thankfully, compilers can't yet make demons fly out of your nose.
Just declaring a variable doesn't necessarily initialize it. int n, m;
leaves both n
and m
with undefined values (in this case, at least), and attempting to access those values is undefined behavior. If the values in the bits of memory those point to happen to be larger than the values entered for n
and m
-- which is very, very far from guaranteed -- then your code will work; if not, it won't. Your compiler could also have made this segfault, or made it melt your CPU; it's undefined behavior, so anything can happen.
For example, let's say that the area of memory dedicated to n
happened to contain the number 87
, and m
got 14
. If you then entered an n
of 12 and an m
of 6, you're golden -- the array happens to be big enough. On the other hand, if n
got 4 and m
got 2, then your code will look past the end of the array, and you'll get undefined behavior. Of course, this is all fluff and speculation depending on the compiler, OS, time of day, and phase of the moon,1 and you can't rely on any numbers happening to be initialized to the right ones.
With the first one, on the other hand, you're assigning the values through scanf
, so (assuming it doesn't error) (and the entered numbers aren't negative) (or zero) you're guaranteed to have valid indices, because the array is guaranteed to be big enough because the variables are initialized properly.
Just to be clear, even though variables are reliably zero-initialized under some circumstances doesn't mean you should rely on that behavior. You should always explicitly give variables a default value, or initialize them as soon as possible after their declaration.
1: Source: Ryan Bemrose, in chat
n
andm
aren't initialised. Theint X[n][m];
uses the valuesm
andn
have at that point in the code -- you can't just set them later, nor can you resize the array by changing them later. – Dmitri Jul 7 at 2:09