Difference between revisions of "W1201 Scope"
Line 18: | Line 18: | ||
== Not All L-Values are Created Equal == | == Not All L-Values are Created Equal == | ||
[[File:Typical computer data memory arrangement.png|thumb|right|link=|Typical Memory Layout]] | [[File:Typical computer data memory arrangement.png|thumb|right|link=|Typical Memory Layout]] | ||
Review our previous discussion about [[W1038 L-Values and R-Values]]. It's clear that the defining difference is that L-Values persist beyond a single expression, and are addressable somewhere in main memory. The big question is, where? | Review our previous discussion about [[W1038 L-Values and R-Values]]. It's clear that the defining difference is that L-Values persist beyond a single expression, and are addressable somewhere in main memory. The big question is, where? To better understand this, we'll need to take a deeper look at the typical memory layout of a program. | ||
== Program Memory Layout == | |||
=== TEXT === | |||
Program memory is divided into several different sections, often called '''segments'''. Logically, every program must have a least one segment, the executable code itself. This is typically stored as '''read-only''' (i.e. it may not be modified) and is referred to as "TEXT". | |||
<syntaxhighlight lang="swift"> | |||
func f() { | |||
print("Hello, World!") | |||
} | |||
</syntaxhighlight> | |||
=== DATA === | |||
The next segment is referred to as "DATA". It contains initialized memory, generally global or static variables assigned a specific value. The values themselves are actually stored in the TEXT segment and copied to the DATA segment during program startup. This segment is '''read-write'''. | |||
<syntaxhighlight lang="swift"> | |||
let x = 7 | |||
</syntaxhighlight> | |||
=== BSS === | |||
The "BSS" segment contains uninitialized memory, generally global or static variables which have not been assigned a specific value. This segment is '''read-write'''. | |||
<syntaxhighlight lang="swift"> | |||
let x : Int | |||
</syntaxhighlight> | |||
The remainder of memory is '''read-write''' and managed dynamically, likely changing frequently as the program executes. It's divided into two main areas. | |||
=== The Heap === | |||
The '''heap''' area begins where the DATA and BSS segments end. Memory is allocated dynamically within this area, as needed. | |||
=== The Stack === | |||
The stack area begins from a high-point in memory and usually '''grows downward''', toward the heap. It's a very important structure and is responsible for the orderly execution of function invocations. The stack area is organized into a series of '''frames''', one for each function invocation. The frame contains the '''return address''', i.e. the location in memory to which the function will return when it completes execution, as well as any '''local variables'''. | |||
<br all/> | |||
== Experiment == | == Experiment == |
Revision as of 21:34, 2 December 2019
Prerequisites[edit]
Research[edit]
- Read Scope (Wikipedia)
- Read Computer Science I Textbook (by Bourke) Chapter 2.2.4. Scoping
Introduction[edit]
The lifetime of a variable is the time period in which the variable has memory allocated to it and may legitimately be referenced.
The scope of a declaration is that part of the code in which the declaration is in effect.
The visibility of a declaration refers to that part of the code in which the declaration is accessible (not hidden) by an identical declaration in another scope.
To best understand these terms, we'll look at several examples below. Beforehand, however, let's revisit our discussion about L-Values.
Not All L-Values are Created Equal[edit]
Review our previous discussion about W1038 L-Values and R-Values. It's clear that the defining difference is that L-Values persist beyond a single expression, and are addressable somewhere in main memory. The big question is, where? To better understand this, we'll need to take a deeper look at the typical memory layout of a program.
Program Memory Layout[edit]
TEXT[edit]
Program memory is divided into several different sections, often called segments. Logically, every program must have a least one segment, the executable code itself. This is typically stored as read-only (i.e. it may not be modified) and is referred to as "TEXT".
func f() {
print("Hello, World!")
}
DATA[edit]
The next segment is referred to as "DATA". It contains initialized memory, generally global or static variables assigned a specific value. The values themselves are actually stored in the TEXT segment and copied to the DATA segment during program startup. This segment is read-write.
let x = 7
BSS[edit]
The "BSS" segment contains uninitialized memory, generally global or static variables which have not been assigned a specific value. This segment is read-write.
let x : Int
The remainder of memory is read-write and managed dynamically, likely changing frequently as the program executes. It's divided into two main areas.
The Heap[edit]
The heap area begins where the DATA and BSS segments end. Memory is allocated dynamically within this area, as needed.
The Stack[edit]
The stack area begins from a high-point in memory and usually grows downward, toward the heap. It's a very important structure and is responsible for the orderly execution of function invocations. The stack area is organized into a series of frames, one for each function invocation. The frame contains the return address, i.e. the location in memory to which the function will return when it completes execution, as well as any local variables.
Experiment[edit]
Create a directory within your "project" directory.
cd ~/projects
mkdir project-1201
cd project-1201
Edit a new file named "main.swift"
emacs main.swift
For each question, be sure to understand the behavior before proceeding to the next question. It will be helpful to record your answers and reasoning for later review.