116 3. Fundamentals of Software Engineering for Games
= 3.141592f;) and all global object instances that have been declared
with the const keyword (e.g., const Foo gReadOnlyFoo;) reside in
this segment. Note that integer constants (e.g., const int kMaxMon-
sters = 255;) are oft en used as manifest constants by the compiler,
meaning that they are inserted directly into the machine code wherever
they are used. Such constants occupy storage in the text segment, but
they are not present in the read-only data segment.
Global variables, i.e., variables defi ned at fi le scope outside any function or
class declaration, are stored in either the data or BSS segments, depending on
whether or not they have been initialized. The following global will be stored
in the data segment, because it has been initialized:
foo.cpp
F32 gInitializedGlobal = -2.0f;
and the following global will be allocated and initialized to zero by the operat-
ing system , based on the specifi cations given in the BSS segment, because it
has not been initialized by the programmer:
foo.cpp
F32 gUninitializedGlobal;
We’ve seen that the static keyword can be used to give a global vari-
able or function defi nition internal linkage, meaning that it will be “hidden”
from other translation units. The static keyword can also be used to declare
a global variable within a function. A function-static variable is lexically scoped
to the function in which it is declared (i.e., the variable’s name can only be
“seen” inside the function). It is initialized the fi rst time the function is called
(rather than before main() is called as with fi le-scope statics). But in terms of
memory layout in the executable image, a function-static variable acts identi-
cally to a fi le-static global variable—it is stored in either the data or BSS seg-
ment based on whether or not it has been initialized.
void readHitchhikersGuide(U32 book)
{
static U32 sBooksInTheTrilogy = 5; // data segment
static U32 sBooksRead; // BSS segment
// ...
}
3.2.3.2. Program Stack
When an executable program is loaded into memory and run, the operating
system reserves an area of memory for the program stack. Whenever a function
is called, a contiguous area of stack memory is pushed onto the stack—we call
this block of memory a stack frame. If function a() calls another function b(),