I have not been able to reproduce this behavior on my SLES 10 box (gcc 4.1.2, yes it's old). I get a segfault regardless of how lim is declared.
I'm going to go way, way, way, way out on a very skinny limb and point out that your definition of main is incorrect; argv should not be declared const (the standard mandates that the strings pointed to by the argv array should be modifiable). That bit of undefined behavior might be enough to cause the difference, but I seriously doubt it.
Either way, attempting to allocate 2 million anything in an auto array (VLA or not) is almost always bad juju. Maybe when computer memory is regularly measured in terabytes it won't be a problem anymore, but for now it's going to be bigger than the runtime stack is usually prepared to handle.
You have a few options available. One, you can declare the array with static storage duration, either by declaring it at file scope (outside of any function) or with the static keyword. Note this means you will not be able to use the lim variable to specify the size (even though you declare it const, lim is not a constant expression; its value is not known at compile time):
int main( int argc, char **argv )
{
static unsigned long long nums2lim[2000000];
...
}
Alternately, you can allocate it from the heap at runtime:
int main( int argc, char **argv )
{
const unsigned long long lim=2000000;
int *nums2lim = malloc( sizeof *nums2lim * lim );
if ( nums2lim )
{
...
}
...
}