CS253: Software Development with C++

Fall 2020

Pet Peeves

Show Lecture.PetPeeves as a slide show.

CS253 Pet Peeves

made at imgflip.com

Guessing

Student: It doesn’t compile when I use ifstream.
Jack: Each class comes from a header file. You must include it.
Student: Is it <ifstream>?
Jack: You’re guessing.
Student: Is it <iostream>?
Jack: Stop guessing. Look it up in https://cplusplus.com or https://cppreference.com.
Student: I know! It’s <cout>!
Jack: sigh

Albert Einstein, they say, didn’t know the speed of sound, but knew where to look it up.

void main()

made at imgflip.com

endl vs. '\n'

cout << "Scarecrow"     << endl;
cout << "Tin Man"       << '\n';
cout << "Cowardly Lion" << "\n";
Scarecrow
Tin Man
Cowardly Lion

endl alternatives

cout << "Scarecrow"     << '\n'
     << "Tin Man"       << '\n'
     << "Cowardly Lion" << '\n';
Scarecrow
Tin Man
Cowardly Lion

cout << "Scarecrow\n"
     << "Tin Man\n"
     << "Cowardly Lion\n";
Scarecrow
Tin Man
Cowardly Lion

cout << "Scarecrow\n"
        "Tin Man\n"
        "Cowardly Lion\n";
Scarecrow
Tin Man
Cowardly Lion

cout << "Scarecrow\nTin Man\nCowardly Lion\n";
Scarecrow
Tin Man
Cowardly Lion

ASCII constants

There is no benefit to memorizing the ASCII table, at the cost of program readability.

char c1 = 65;     // Sure, this works.
char c2 = 'A';    // But so does this.
cout << c1 << c2;
AA

Doing work for the computer

Doing work for the computer is like cleaning up for the maid. I see code like this:

    inches = miles * 63660;

When I ask the student, “How’d you come up with that number?”, they say “I multiplied 5280 by 12 on a calculator.” Gosh—that sounds like something that the computer should be doing:

    inches = miles * 5280 * 12; // 5280 feet/mile, 12 inches/foot

Or, depending on how many places you do this:

    constexpr auto feet_per_mile = 5280,
              auto inches_per_foot = 12;
    inches = miles * feet_per_mile * inches_per_foot;

The compiler will fold the constant multiplication for you—it will do the multiplication at compile-time, not during program execution.

Pants on Fire

cout << 5280*12;
63360

Indentation

Indentation is often regarded as useless. As long as the program works, that’s all that matters!

Those of us who have to read and maintain your code disagree.

Casting

Casting is not magic.

char buf[] = "123";
long n = (long) buf;
cout << n << '\n';
140720857833172

If you use casting, then something is wrong. Think again.

vector/string methods

Java programmers love .at(), and refuse to learn about [].
.at() does error checking, [] usually doesn’t.

vector<int> v = {11,22,33};
for (size_t i=0; i<v.size(); i++)
    cout << v.at(i) << ' ';
for (size_t i=0; i<v.size(); i++)
    cout << v[i] << ' ';
11 22 33 11 22 33 

Do we need error checking in that code? Could i get out of range?

Similarly, for strings:

string s = "Jack Applin";
cout << "My initials are " << s[0] << s[5] << '\n';
My initials are JA

Not everything is a reference

You do not have to use new to create an object:

string s;
s.push_back('C');
s += 'S';
s += "U";
cout << s << '\n';
CSU

.eof() does not predict

.eof() does not mean “Will the next read fail?”.

ifstream in("/etc/hostname");
int count=0;
while (!in.eof()) {
    string s;
    getline(in, s);
    cout << ++count << ": " << s << '\n';
}
1: beethoven
2: 

.eof() means “Did the previous read fail?”.

ifstream in("/etc/hostname");
string s;
int count=0;
while (getline(in, s))
    cout << ++count << ": " << s << '\n';
1: beethoven

Boolean is hard!

It’s ok to use boolean values as values, not just in if and while:

char c = 'a';
bool vowel;
if (c=='a' || c=='e' || c=='i' || c=='o' || c=='u')
    vowel=true;
else
    vowel=false;
cout << boolalpha << vowel << '\n';
true
char c = 'a';
bool vowel = (c=='a' || c=='e' || c=='i' || c=='o' || c=='u');
cout << boolalpha << vowel << '\n';
true

Return is easy

return is not a function, so parentheses are not required:

int main() {
    cout << "Hello\n";
    return 0;  // Note lack of parens
}
Hello

throw

string s = "foo";
cout << s.at(9);
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::at: __n (which is 9) >= this->size() (which is 3)
SIGABRT: Aborted

And …

Equating “literally” and “figuratively”
“My head literally exploded!”
Regarding all odds as 50/50
“I might win the lottery, I might not. It’s 50/50.”
Confusing “strict“ or “harsh” with “unfair”
“The average on the midterm was 60%? That’s totally unfair!”