CS253: Software Development with C++

Fall 2021

Traps

Show Lecture.Traps as a slide show.

CS253 Traps

C++ traps for the unwary Java programmer

♥️ ☕️

Prophecy

In 1572, Nostradamus wrote:

When penning in what was twice made more,

In the high city with walls that guard, Beardless scholars who love beans as black as tar, Will shine like the Captain of France

This was recently translated as:
When programming in C++,

In Fort Collins, Colorado, Students who love Java, Will pull out their hair

Age

If you ask, “Why doesn’t C++ do such-and-such a thing like Java?”, then you’re asking the wrong question.

I resemble my father—he doesn’t resemble me.

Methods & Functions

main

In C++, the main() function returns an int indicating success/failure. Zero means success, positive numbers means failure. It’s not a boolean value—it’s an integer code.

In C++, main() uses an array of old-style C char * strings, for compatibility with C.

Poor George Boole

bool b = true;
if (b)
    cout << "C++ rules!\n";
C++ rules!
boolean b = true;
if (b)
    System.out.println("Java drools!");
Java drools!

Neither is “Boole”, which was the guy’s name.

Booleanosity

In Java, true is true. In C++, a non-zero value is true. So is a pointer, unless it’s nullptr.

if (42)
    System.out.println("true in Java");
Code.java:1: error: incompatible types: int cannot be converted to boolean
class Code { public static void main(String[] args) { if (42)
                                                          ^
1 error
if (true && 42 && 3.14159 && 'x' && "hello")
    cout << "true in C++\n";
true in C++

Byte

C++’s char type is the closest approximation to Java’s byte.

Java’s char can hold Unicode characters. C++’s char has an implementation-defined size, but it’s typically a single byte, so ASCII only—no ñ, ⻥, or 😈.

final/const/constexpr

In Java, final indicates a non-overrideable method, or a constant value.

In C++, final indicates a non-overridable method. const indicates a method that doesn’t alter object state, or a value that you can’t change. constexpr indicates a compile-time constant.

Arrays

In C++, arrays are not objects. Hence, they have no methods. Hence, you can’t ask an array how long it is. Use a vector or std::array instead, if you want that.

The simple term “array” is, alas, ambiguous. We will use the phrases “C-style array” or std::array to resolve this.

Strings

In Java, classes start with a capital letter. That’s not always so in C++.

"what type am I?"

Objects: heap or not?

String Subscripting

String s = "abcdefg";
System.out.println(s.charAt(3));
d
string s = "hijklmn";
cout << s[3] << '\n';
cout << s.at(4) << '\n';
k
l

Order of Operations

Java yields 5, because the order of operations is defined: left side ++, then right side --, then +.

int n=2;
System.out.print(++n + --n);
5

C++ invokes undefined behavior. The compiler is free to do the operations (+++--) in whatever order it likes. The compiler is not required to tell you that you broke the rules, though a good compiler might, if you ask nicely (-Wall):

int n=2;
cout << ++n + --n;
c.cc:2: warning: operation on 'n' may be undefined
4

Plus-sign overloading

System.out.println("foobar"+3);
foobar3
cout << "foobar"+3 << '\n';
bar

In Java, + is overloaded to handle arguments of String and int, and so yields "foobar3".

C++ performs address arithmetic in this case, and so yields "bar".

Pointers and references

int[] reed = {1,2,3}, sue = reed;
// In Java, reed & sue share data.
reed[0] = 4;
System.out.println(reed[0] + " " + sue[0]);
4 4

vector<int> ben = {1,2,3}, johnny = ben;
// In C++, johnny is a copy of ben.
ben[0] = 4;
cout << ben[0] << ' ' << johnny[0] << '\n';
4 1

This C++ code uses no pointers or references.

Copying

In Java, this copies a reference. No new object is created, no real data is copied. This is a shallow copy. If I modify obj2, it changes obj1, because there’s only one object, with two references to it.

In C++, the copy ctor of the class is called. This typically copies the data in the object, making this a deep copy. If I modify obj2, obj1 doesn’t change—they’re separate objects.

Method/Member Access

String s = "foobar";
System.out.println(s.length());
6
string a = "xyzzy";
string *b = new string("alakazam");
cout << a.length() << ' ' << b->length() << '\n';
cout << a.size()   << ' ' << b->size()   << '\n';
5 8
5 8

Garbage Collection

In C++, your options are (hardest to easiest):

Out of Bounds


Faith, the Vampire Slayer
int[] a = {11, 22, 33};
System.out.println(a[-9]);
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -9
	at Code.main(Code.java:2)
int a[] = {44, 55, 66};
cout << a[-9]        << endl;
cout << a[-90000000] << endl;
119704784
SIGSEGV: Segmentation fault

Nothingness

In Java, null is the reference to nothing.

In C++, a pointer to nothing useful can be initialized to nullptr or NULL or 0.

Really, just pointers

⁰/₁

Parting Shot

made at imgflip.com