You wrote in a comment:
The execution is done line-by-line. The only way to find the value returned by Func_i() is to jump out of the main
That's a misconception: Execution isn't don line-by-line. Compilation is done line by line, and name resolution is done during compilation, and it only resolves names, not return values.
A helpful conceptual model is this: When the compiler reads the line:
printf("func:%d",Func_i());
it emits code equivalent to:
1. call "function #2" and put the return value on the stack
2. put the constant string "func:%d" on the stack
3. call "function #1"
The compiler also makes a note in some internal table that function #2
is a not yet declared function named Func_i
, that takes an unspecified number of arguments and returns an int (the default).
Later, when it parses this:
int Func_i() { ...
the compiler looks up Func_i
in the table mentioned above and checks if the parameters and the return type match. If they don't, it stops with an error message. If they do, it adds the current address to the internal function table and goes on to the next line.
So, the compiler didn't "look" for Func_i
when it parsed the first reference. It simply made a note in some table, the went on parsing the next line. And at the end of the file, it has an object file, and a list of jump addresses.
Later, the linker takes all this, and replaces all pointers to "function #2" with the actual jump address, so it emits something like:
call 0x0001215 and put the result on the stack
put constant ... on the stack
call ...
...
[at offset 0x0001215 in the file, compiled result of Func_i]:
put 3 on the stack
return top of the stack
... [at offset 0x0001215 in the file, compiled result of Func_i]: put 3 on the stack return top of the stack
Much later, when the executable file is run, the jump address is already resolved, and the computer can just jump to address 0x1215. No name lookup required.
Disclaimer: As I said, that's a conceptual model, and the real world is more complicated. Compilers and linkers do all kinds of crazy optimizations today. They even might "jump up an down" to look for Func_i
, although I doubt it. But the C languages is defined in a way that you could write a super-simple compiler like that. So most of the time, it's a very useful model.