The BSS section of the static memory layout is [supposed to be] for
"Uninitialized global variables" or "Global variables set to 0".
It's unclear where you got that impression, but it is at best misleading. Most people using the term "global variable" in C context mean an object identifier with external linkage, which is necessarily for an object with static storage duration. With a few provisos, such an identifier can be used anywhere in a program to refer to the same object, hence "global". The existence and nature of some of the provisos make use of the term "global" for these a bit fraught, but I'll leave that for a different answer.
The key point there with respect to BSS is not the linkage but the storage duration. Static storage duration means that, at least in principle, the object comes into existence* at or before the beginning of the program and lives (at least) until the program terminates. Contrast with variables declared at block scope without static
: these have automatic storage duration, meaning they come into existence at the point of declaration, and live only until execution of their innermost containing block terminates.
Objects with static storage duration need to be represented in the program image, regardless of their linkage, because they have the same lifetime as the program itself. C specifies that in the event that such objects are not explicitly initialized, their initial values are as if they were initialized to 0 (for numeric types) or to NULL
(pointer types) or memberwise to these for compound types. BSS is a space- and time-saving shortcut for representing storage for such objects and for those explicitly intialized to 0.
So-called "global" variables that satisfy the initialization conditions can be and typically are attributed to the BSS, but so are
- file-scope variables with internal linkage (the effect of
static
on declarations at that scope; these automatically have static storage duration but are accessible only from one source file, and
- block-scope variables with static storage duration, as specified by use of the
static
keyword at that scope, even though these have no linkage.
*In C++, some of these are subject to dynamic initialization at a later time, but memory for such objects is still reserved for the entire run of the program, and they are subject to zero initialization at program startup. That they have memory reserved and well-defined value constitutes existence for the purposes of this answer.