University of Michigan at Ann Arbor
Last Edit Date: 01/09/2023
Disclaimer and Term of Use:
We do not guarantee the accuracy and completeness of the summary content. Some of the course material may not be included, and some of the content in the summary may not be correct. You should use this file properly and legally. We are not responsible for any results from using this file
This personal note is adapted from Professor Amir Kamil, Andrew DeOrio, James Juett, Sofia Saleem, and Saquib Razak. Please contact us to delete this file if you think your rights have been violated.
This work is licensed under a Creative Commons Attribution 4.0 International License.
A machine model helps use understand how the source code relates to what happen at runtime.
Take the following code as an example:
1 int main() { 2 int x = 3; 3 double y = 4.1; 4 int z = x; 5 x = 5; 6 }
Try it out:
Click here to open in new windowThe program executes from main()
. Then excutes the rest code line by line. We can consider the basic machine model where memory is represented as a big array, with each index in the array corresponding to a memory location that can hold a value.
The following picture shows the process of how the code is executed line by line.
2.int x = 3;
4.int z = x;
5.x = 5;
3.double y = 4.1;
Name: A name refers to some entity such as a variable, function, or type. A name has a scope, which determines what region of code can use that name to refer to an entity.
Variable: A variable is a name that refers to an object in memory.
Declaration: A declaration is what introduces a name into the program and begins its scope.
Object: At runtime, an object is a piece of data in memory, and it is located at some address in memroy (corresponding to the index in our basic machine model above.) An object is created at some point in time, and at some later point in time it is destriyed.
Storage: The storage duration of an object determines its lifetime. There are three options in C++:
Static: the lifetime is essentially the whole program. (Controlled by the complier)
Automatic (also called local): the lifetime is tied to a particular scope, such as a block of code. (Controlled by the complier)
Dynamic: the object is explicitly created and destroyed by the programmer. (Controlled by the programmer)
In C++, the default is value semantics. Take the following code as an example:
1 int x = 42; // initialize value of x to 42 2 int y = 99; // initialize value of y to 99 3 x = y; // assign value of y to value of x
The assignment in the last line copies the value stored in the memory object associated with y
into the memory object for x
, as shown below.
C++ also has reference semantics only when initializing a new variable. Simply put a &
to the left of the new variable name can make the name to be associated with an existing object. Take the following code as an example:
1 int x = 42; // initialize value of x to 42 2 int z = 3; // initialize value of z to 3 3 int &y = x; // y and x are now names for the same object 4 x = 24; // assigns 24 to object named x/y 6 y = z; // Does NOT re-bind y to a different object
The declaration int &y = x;
introduces y
as a new name for the object associated with x
. Any subsequent modification to this object is reflected through both names, regradless of the name used to perform the modification. The process is shown as below.
Since C++ only supports reference semantics in initialization, the association between a variable and a memory object can never be broken, except when the variable goes out of scope.