I recently wrote my first C program: a simple number-guessing game. I have some experience with Python, so loops and conditionals were familiar, but I'm still learning how C handles variables and program startup.
My code includes this line before main():
int num = rand() % 100 + 1;
The compiler rejects it because rand() is not a compile-time constant. When I move the declaration inside main(), it works:
int main(void) {
int num = rand() % 100 + 1;
// ...
}
Could someone explain in simple terms why a global variable cannot be initialized by calling rand(), while a local variable can? I'd also appreciate any other suggestions for improving this beginner program.
3 Answers
The program performs startup work before main() begins, including setting up objects with static storage duration, such as global variables. That setup is not a normal sequence of C statements where arbitrary functions can be called. The compiler prepares the initial memory contents ahead of time, so those initial values generally need to be known during compilation. A call to rand(), the current time, or input from a user cannot meet that requirement because those values only exist at runtime.
One more issue: unless you seed the pseudo-random generator, rand() will usually produce the same sequence every time the program starts. A common beginner approach is to seed it once in main(), for example with srand((unsigned)time(NULL)); after including time.h. Then initialize num afterward. Also consider checking the return value of scanf(), because entering text instead of a number can leave the input in the buffer and make the loop behave unexpectedly.
At file scope, a variable’s initial value has to be something the compiler can determine while building the program, such as 10, 2 + 3, or another valid constant expression. rand() is a function that only runs while the program is executing, so its result is unknown when the compiler is creating the global data. That is why this fails:
int num = rand() % 100 + 1;
Putting it inside main() works because local initialization happens during execution, after the program has started. There’s also no real reason for num to be global here; keeping it inside main() limits its scope and makes the program easier to understand and maintain.

That makes sense. I had assumed rand() was somehow evaluated before the program started, but it’s clearer now that it has to execute during runtime. I’ll look into seeding it and validating scanf() next.