Show Lecture.Const as a slide show.
CS253 Const
- const, when applied to a variable, means that you can’t change it.
- It’s like a
final
variable in Java.
- It does not mean that the memory is read-only;
it just means that you can’t write it.
- A given piece of memory may be read-only to one part of a program,
but read-write to another.
- const is also used to indicate an accessor (getter) method.
Example
const int BOARD_SIZE = 8;
char chessboard[BOARD_SIZE][BOARD_SIZE];
for (int i=0; i<BOARD_SIZE; i++)
for (int j=0; j<BOARD_SIZE; j++)
chessboard[i][j] = ' ';
if (chessboard[3][2] == ' ') // Empty position?
chessboard[3][2] = 'R'; // put a rook there
cout << chessboard[3][2] << '\n';
R
Reference example
void show_name(const string &name) {
cout << "The name is: “" << name << "”\n";
}
int main(int, char *argv[]) {
string s = argv[0];
show_name(s);
}
The name is: “./a.out”
- The string is read-write in main(),
but read-only in
show_name()
.
- The string memory itself is read-write. It’s just that
show_name()
promises not to change it.
It’s all relative
int president = 46;
int &prez = president;
const int &potus = president;
prez = 1; // ok
potus = 2; // 🦡 bad
c.cc:5: error: assignment of read-only reference ‘potus’
- Wait—is
president
read-only or read-write?
- It depends how you access it.
prez
is a read-write view (aspect, avatar) of president
.
potus
is a read-only view of president
.
- Same as how my lunch is read-write to me,
but read-only to you.
- constexpr, when applied to a variable, means that you can’t change
it, it never changes, and was computed at compile-time.
- Since the value never changes, the compiler it can substitute the
value wherever you use the variable.
- Use it for true constants:
- π, Avogadro’s Number
- number of days in a week
- number of squares in a chessboard
- We used to do this in the preprocessor with
#define TRIPLE_POINT 32.018
,
which still works, but this is better.
- It’s a shame to call it a “variable” if it never “varies”,
but that’s how we talk.
Examples
constexpr auto π = 3.14159;
cout << π << '\n';
3.14159
constexpr double avo=6.022e23;
avo = 1.234; // 🦡 badness
cout << avo;
c.cc:2: error: assignment of read-only variable ‘avo’
// Oops: process id not known at compile time:
constexpr double pid = getpid(); // 🦡
cout << pid;
c.cc:2: error: call to non-‘constexpr’ function ‘__pid_t getpid()’
Trying to cheat
Let’s try to fool constexpr:
constexpr int answer = 42;
int *p = &answer; // 🦡
*p = 8675309;
cout << answer << '\n';
c.cc:2: error: invalid conversion from ‘const int*’ to ‘int*’
constexpr int answer = 42;
int *p = const_cast<int *>(&answer); // 🦡
*p = 8675309;
cout << *p << ' ' << answer << '\n';
8675309 42
Why two different values?
answer
is constexpr, so our compiler substituted 42
for
answer
in the machine code. No fetching, no memory locations—just
an inline Platonic 42,
unchanged by the cheating code.