creates a variable i with global scope and internal linkage. Meaning anyone can refer to it but only entries within the translation unit(.c file) will not break the linker. It is allocated during program linking and is initialized before main() is entered.
Correct, except the formal term is file scope (outside any function), not to mixed up with "global" which can often mean accessible everywhere. In this case the variable is declared at file scope but it is not "globally" accessible. Generally, the informal term "global" is used together with the formal term external linkage and usage of the extern
keyword.
creates a variable with function scope and no linkage.
No, it creates a variable with block scope. There exists a formal term function scope but it refers to the scope of goto
labels. C has four scopes: file scope, function scope, block scope and function prototype scope. Those who aren't language lawyers or spaghetti programmers only need to know about file scope and block scope.
Meaning nothing outside of foo() can refer to it
Correct.
even if the compiler didn't cry out, taking the address of this (essentially protected global) variable is UB
No, this is wrong. Scope doesn't determine if a variable can be accessed or not, storage duration does. Both your examples declare variables with the same static storage duration but with different scopes. A variable with static storage duration persists and remains valid throughout the execution of the program.
Therefore it is fine and well-defined to return a pointer to a block scope variable with static storage duration. (It may not be thread-safe however, but that's another story.)
It is allocated during program linking
Correct.
and is initialized when foo() is first called.
No, this is wrong. All variables with static storage duration, regardless of their scope, are initialized before main() is called. Either to an explicit initializer as in your examples (typically meaning it gets allocated in a segment named .data
) or to zero in case it wasn't explicitly initialized (all static storage variables set to zero typically gets allocated in a segment named .bss
).