C++
January 7, 2019
Mike Spertus
mike_spertus@symantec.com
This week’s lecture
⚫ The first half of today’s lecture is a survey of
C++
⚫ Want to give some of the big picture without
worrying too much about the technical details
⚫ Don’t worry if some things are unclear or not
covered in enough depth
⚫ We’ll come back and start presenting language
features systematically starting at “Hello, World”
starting in the second half of the lecture
COURSE INFO
Who am I?
⚫ Day job at Symantec
⚫ Fellow and Chief Scientist for Cyber Security Services where my job is to help
turn Symantec into a security as a service company
⚫ Chief Architect for our Authoritative Data Lake, which will contain trillions of
lines of security telemetry across dozens of products
▪ MPCS53013 Big Data is based off this!
⚫ A long-time member of the ANSI/ISO C++ committee
⚫ Written over 50 C++ standards proposals, including C++11 non-static
data member initializers, and C++17’ Constructor Template Argument
Deduction
⚫ Consider joining the standards committee. It’s the best way to learn C++
☺
⚫ Co-authored one of the first C compiler for the original IBM PC
AT
⚫ I tell bad jokes. Get used to it
⚫ Available at mike@spertus.com. Use it!
⚫ Today is my birthday ☺
Useful Resources: Web
⚫ C++17 Standard. Use near-final draft at
http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
⚫ http://isocpp.org/
⚫ The C++ core guidelines is the best place to find out the currently
recommended best practices
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
⚫ http://www.open-std.org/jtc1/sc22/wg21/, the ISO committee
website
⚫ http://herbsutter.com/ - Herb is the Convener of the standards
committee
⚫ Online compilers, very useful
⚫ https://wandbox.org
⚫ Compiler Explorer at https://godbolt.org
⚫ The C++ section of StackOverflow, cppreference.com, and r/cpp
are all pretty good (cplusplus.com not so much)
Useful Resources: Books
⚫ Books from Bjarne Stroustrup, the inventor of C++. Be sure to use the
latest editions
⚫ A Tour of C++ (2nd edition) – C++ for programmers, just like this course!
⚫ The C++ Programming Language (4th edition) – a thorough reference but only
covers through C++14
⚫ Programming: Principles and Practices – An intro to programming using C++.
Don’t be afraid to use it
⚫ Nico Josuttis, The C++ Standard Library, A Tutorial and Reference
⚫ As we will see, programming languages are as much about the standard library
as the language itself
⚫ Only covers through C++11: Still very good but no filesystem, parallel algorithms,
shared mutexes, user-defined literals for time, etc.
⚫ Josuttis and Vandervoorde, C++ Templates: The Complete Guide (2nd
Edition)
⚫ As you will see, much of the course will be about templates in one guise or other.
⚫ Anthony Williams, C++ Concurrency in Action (2nd edition)
⚫ C++ multithreading. Our main topic for the last few weeks.
⚫ If you don’t want to buy/read the whole book, Anthony’s blog gives most of what
you need in his multithreading in C++ series
⚫ http://www.justsoftwaresolutions.co.uk/threading/multithreading-in-c++0x-part-1-starting-
threads.htm
The most important rule
⚫ If you are ever stuck or have questions or comments
⚫ Be sure to contact me
⚫ mike@spertus.com
⚫ Or your TAs
⚫ David Manglano: david.manglano@gmail.com
⚫ Patrick Shriwise: pshriwise@anl.gov
⚫ Kelvin Ho: kelvinho@uchicago.edu
⚫ Office hours:
⚫ Mike: Crerar 352: 3-5 on Mondays
⚫ David: Thursday: 1-4
⚫ Patrick: Friday: 1-4
⚫ Kelvin: After class in Ry251
⚫ Anyone: By arrangement
Homework and Lecture Notes
⚫ Homework and lecture notes posted on Canvas
⚫ Choose MPCS 51044 and then go to “Pages”
⚫ Add yourself to our Piazza group
⚫ You can access it from the Piazza tab on Canvas or by logging
into Piazza directly
⚫ HW due on the following Monday before class
⚫ Graded homework will be returned by the start of the
following class
⚫
⚫ Since I go over the answers in class, no late homework will be
accepted
⚫ ☺
⚫ If you submit by Thursday Midnight, you will receive a grade and
comments back by Saturday, so you can try submitting again
Setting up Gitlab to submit
homework
⚫ Sign into gitlab with your UChicago ID at
https://rev.cs.uchicago.edu/
⚫ Create a project named
2019mpcs51044-<your_cnet_id>
⚫ e.g. 2019mpcs51044-jsmith
⚫ Follow the instructions to create and register an
ssh key with GitLab at
https://docs.gitlab.com/ce/ssh/README.html
⚫ Note: you may already have one, in which case, just
register it with GitLab
Setting up GitLab (continued)
⚫ Go to Members under Settings
⚫ Add the following accounts as Reporters on your
project:
⚫ @spertus, @manglano, @kelvinho, @shriwise
⚫ Follow the instructions to verify that you can
clone and push to your repository
⚫ For each homework, create a branch to contain
the homework
⚫ Send an email with mpcs51044 in the subject to
david.manglano@gmail.com notifying David
that you have created your repository
Grading
⚫ 2/3 HW
⚫ Many extra credit opportunities
⚫ Extra credit can get your HW total for the quarter
to 100% (but no higher) to cancel out any
problems you miss
⚫ 1/3 Final
⚫ The biggest part of the final is to do a code review
of a willfully bad (but unfortunately not worse than
some code you’ll see in real-life) program
C++ for programmers?
⚫ Prior knowledge of C++ helpful but not required
⚫ Expect you know how to program in some
language
⚫ This is “not an introduction to programming” class
⚫ Gloss over features that are similar to those in
Java, C, etc.: if, for, ?:,…
⚫ OK if these are unfamiliar to you
⚫ Ask questions in class
⚫ Email or IM me or the Tas
⚫ Look up in the many recommended texts
C++ for programmers?
⚫ This class concentrates on two things
⚫ C++
⚫ As we will see, C++ is fundamentally different from other languages you
might be familiar with, such as Java or C
⚫ Advanced Programming
⚫ While most students have gotten a basic “how to program” intro from a
class, friend, YouTube, etc., it’s hard to find material to systematically
present advanced programming techniques that are so important to
becoming an expert
⚫ For example, programming the cache is incredibly important in today’s
multicore world and has a well-understood set of best practices, but very
few programmers know them
⚫ This really doesn’t have much to do with C++ in particular, but what’s the
point in becoming a C++ expert if you aren’t an expert programmer?
⚫ Indeed, the cache programming practices I will present are derived from a
Java-based text
⚫ Risk reduction: The goal is that you will learn things from this class that you
will use every day regardless of what language you use
What have you heard about
C++?
⚫ C++ is complicated and difficult to learn
⚫ C++ is unsafe
⚫ You can scribble over memory and crash your
program
⚫ C++ is an incoherent mashup of every other
programming language
⚫ See C++ considered harmful for more
These are all true, but…
…that’s a good thing
⚫ At least for some use cases
⚫ Most languages omit features that programmers often use
incorrectly
⚫ Fewer bugs in code by unknowledgeable programmers
⚫ C++ includes features if they support important use cases
even if they can be misused by the uninformed
⚫ The committee believes it is not unreasonable to expect
professional programmers to spend time studying the tools
they use every day
⚫ With C++, you won’t bring a knife to a gunfight, but make sure
you are expert enough to not shoot off your own foot
⚫ Most of the advanced difficult features are for writing
libraries. This can make writing applications in C++ easier
than in other languages
Most devs learn C++ on the
street and end up hating it
⚫ It certainly didn’t work for me
⚫ After over a decade of picking up C++ through general
exposure and writing commercial C++ libraries, I
thought I was an expert C++ programmer
⚫ Then I joined the C++ standards committee and found
out I wasn’t
⚫ The real inventors of C++ routinely used many
powerful C++ techniques and idioms that I had never
heard of
⚫ Their libraries were much more powerful,
flexible, performant, and easy to use than any I
had produced are even imagined
A brief history of C++
⚫ 1979 “C with classes” invented by Bjarne Stroustrup
⚫ 1983 Renamed C++
⚫ 1998 First standard.
⚫ Boost libraries released
⚫ 2003 A minor standard revision
⚫ Primarily fixed defects in the 1998 wording
⚫ 2011 C++11 standard.
⚫ Called C++0X under development so “X” ended up being “b”! (We were overly ambitious)
⚫ Bjarne Stroustrup says it seems like a “Whole New Language”
⚫ This course will spend a lot of time on the new C++11 features
⚫ 2014 C++14
⚫ The current standard
⚫ A smaller release with small “why didn’t we do that” features that make a big difference
⚫ 2017 C++17
⚫ Medium-sized release mainly around library improvements: parallel algorithms, filesystem,
string_view, optional, any, variant (tagged unions)
⚫ 2020? C++20
⚫ Major release including Concepts (a type system for generic programming), Contract support,
Ranges (a more functional approach to algorithms on containers or other ranges), …
C++ is a standard
⚫ The standard is your toolbox
⚫ C++ is a large language. When questions arise (and they
will), the standard is the authoritative answer
⚫ Standardized in 1998
⚫ Minor revision in 2003
⚫ Major update in 2011
⚫ Medium update in 2014
⚫ Accurate in all significant ways but a “draft” to meet ISO
requirements limiting free public access to the actual
standard
⚫ The current standard is C++17
⚫ All modern compilers support C++98 and C++11 very well
⚫ C++14 reasonably well
⚫ C++17 sporadically
C++ is not a standard
⚫ Just as important as knowing what the C++ standard says,
you need to know what it doesn’t say
⚫ Even simple code relying on “obvious” non-standardized
behavior may be very fragile
⚫ Relying on non-standard C++ behavior is necessary. E.g.,
⚫ Bits in an integer
⚫ DLLs
⚫ “There are no interesting standards-compliant program”
⚫ However, it reduces portability and is fragile
⚫ If you need to rely on non-standardized behavior (and you
will), try to rely on “implementation-defined” rather than
“undefined” behavior, so at least it is defined somewhere
C++11
⚫ Many new features
⚫ Threads
⚫ Memory model
⚫ Lambdas
⚫ Rvalue references
⚫ Initializer lists
⚫ “auto” variables
⚫ Many more
⚫ http://www2.research.att.com/~bs/C++0xFAQ.html
⚫ You’ll need a relatively new compiler to use these features
⚫ A big part of the course
⚫ See http://www.open-std.org/jtc1/sc22/wg21/ to understand
how the designers of C++ think
C++14
⚫ A smaller release with small “why didn’t we do that”
features that make a big difference
⚫ More production-strength concurrency
⚫ Reader-writer locks are the most important
⚫ Polymorphic lambdas
⚫ Much bigger than it sounds
⚫ We’ll learn what and why later
⚫ Standard user-defined literals
⚫ If a function expects a time, you can pass it any of
1min, 60s, 60000ms, etc. to give it a minute
C++17
⚫ A bit bigger than C++14 but was hoped to be more
⚫ Useful libraries: filesystem, variant, optional,
string_view, etc.
⚫ Parallel algorithms
⚫ Structured binding
⚫ Better support for compile-time programming
⚫ Incredibly practical tweaks like coding portably
around cache line size
⚫ …
What C++ isn’t
⚫ C++ isn’t a better C or a worse Java
⚫ Don't be misled by superficial similarities to C
and Java.
⚫ Good C or Java code is not necessarily good
C++ code
⚫ >90% of C++ programmers make this mistake
⚫ One of my goals today is to convince you that this is
correct
⚫ Knowing how to program in Java, C, or other languages
does not mean you know how to program in C++
What is C++: Hello World
#include <iostream>
int
main()
{
std::cout << "Hello, world!" << std::endl;
return 0;
}
Characteristics of C++
⚫ Multiparadigm
⚫ Lightweight abstractions
⚫ Statically typesafe and (largely) type inferenced
⚫ Methods can specify whether they use the static
or dynamic type of an object
⚫ Supports low-level system programming
⚫ Parameters can be passed by reference or
value
⚫ Pass by value can even select between deep and
shallow copies
⚫ RAII/Exceptions
Multiparadigm
⚫ C++ is not an object oriented language
⚫ C++ supports object-oriented programming
⚫ But it also supports other paradigms
⚫ Indeed, the standard library prefers compile-time
dispatch (templates, see below) and only uses runtime
dispatch in about a dozen places
C++ is a lightweight
abstraction language
⚫ That was the winner when Bjarne Stroustrup moderated a discussion
on the C++ elevator pitch
⚫ This is a mouthful, but I think the idea is right
⚫ Programming languages typically fall into a tradeoff between being
good for programmers (i.e., abstract) or good for computers (i.e., low-
memory. fast, and low-level)
⚫ Abstract but slow/no low-level programming: Python, Java, JavaScript,…
⚫ Efficient but not abstract: C, Assembler,
⚫ The problem is, that we need both as performance vs abstraction
constantly looms over almost all programming decisions
⚫ “Do I want to do it the clear modular, maintainable way or the performant way?”
⚫ Unlike almost any other language, C++ gives you the best of both
world, allowing you to create powerful abstractions that are lightweight
by having all the abstraction “compiled-away” during the build using
“templates”
⚫ In other words, there is no performance penalty associated with
using/creating abstractions
Delivering performance and
abstraction
⚫ C++ delivers performance by being a native language allowing
low-level manipulation of code and data
⚫ No virtual machine, manual memory management, etc.
⚫ C++ delivers abstraction through C++ generics, which use
compile-time computation to generate optimal code
⚫ If you want code that is
⚫ good for the programmer
⚫ clear, consistent, abstract, and extensible libraries
⚫ good for the computer
⚫ great time and space performance
⚫ low-level customizability
⚫ Then C++ is most often the right language
⚫ Note: Many programs don’t need this. C++ has no equivalent of
scripting or IPython notebooks that are great for small scripts
where performance is not paramount
Objects
⚫ We will need to talk about objects in the
upcoming example
⚫ We don’t really know what an object is yet,
but for now, just think of it as some structured
data in memory
⚫ An object can be a simple, contiguous region
of memory, like a number
Lightweight abstractions
Example: Copying objects
⚫ How do we copy one data structure to
another?
⚫ In C, we get low-level performance by
copying the underlying memory with the
memcpy command
⚫ While this is fast, it’s not abstract, so it’s not
fit for production programs that are complex
and need to be evolved over time
⚫ Let’s see why
“Compound” object
⚫ More complex objects may (logically) contain
other objects spread all over memory
⚫ For example, an object representing an
HTML page
Copying a compound object
⚫ In C, if I copy a compound object, only the “root”
is copied
⚫ HTMLPage a;
a = /* ... */; // "Hello" page
b = a; // Oops! Only copies root
⚫ One generally has to manually write
“deep copying” commands in C,
polluting the code with brittle
implementation details
⚫ Can we do better in C++?
Copying compound obj in C++
⚫ We haven’t talked about classes yet, but for now, they are just the way you create your own types
in C++
⚫ C++ classes let you specify a “copy constructor” that explains the right way to copy objects
belonging to that class
⚫ class HTMLPage {
public:
// Copy constructor does deep copy
HTMLPage(HTMLPage const &) { /* ... *}
/* ... */
};
HTMLPage a = /* ... */; // "Hello" page
b = a; // Automatically does deep copy
// Programmer doesn’t care if storage is contiguous
⚫ Abstract: Just copy any object with an assignment, independently of implementation
⚫ Lightweight: The compiler generates the code, so it is just as efficient as-if you did it manually
⚫ b: a:
Lightweight abstractions
Example: Copying containers
⚫ In Java, it is easy to create a new container that is a copy of an old
container
⚫ // https://javarevisited.blogspot.com/2014/03/how-to-
clone-collection-in-java-deep-copy-vs-shallow.html
Collection<Employee> copy = new
HashSet<Employee>(org.size());
Iterator<Employee> iterator = org.iterator();
while(iterator.hasNext()){
copy.add(iterator.next().clone());
}
⚫ This is very abstract, and doesn’t care how the containers and objects
are laid out in memory, so you can change from one type of container
to another without breaking your code, etc.
⚫ However, the price of this abstraction is poor performance as a
contiguous array of primitive objects in memory is inefficiently copied
one object at a time
std::copy
⚫ C++ standard library provides a standard
copy function that is the ultimate in
abstraction
⚫ It can copy from anything to anything else
(anything from memory to containers to the
console) and even does deep copies
⚫ Example: Copying from a vector to array
vector<char> v;
...
copy(v.begin(), v.end(), arr);
copy: A lightweight
abstraction
⚫ As abstract as Java
⚫ Can copy any collection to any other collection with no change to
code
⚫ Less risk of bugs, separates implementation from usage, reduces
brittleness so programs can evolve
⚫ As efficient as C
⚫ The compiler uses a mechanism called template programming to
automatically generate the most efficient code at compile-time,
so if a block-move memory would do the trick, the compiler will
simply generate the same memcpy as C
⚫ This results in an 800% performance improvement in such cases.
Since copying objects is very common, this is not an unimportant
optimization
⚫ We will learn how to write code that does this over the
course of the quarter
STARTING FROM “HELLO
WORLD”
What is C++: Hello World
#include <iostream>
int
main()
{
std::cout << "Hello, world!" << std::endl;
return 0;
}
Defining variables
⚫ // Create an int initialized to 5
int i{5};
int j(5); // Does exactly the same
int k = 5; // Does the same thing
int l; // l could be anything
int m{}; // m is zero
⚫ // Infers type from initializer
auto i{5};
// i is a variable. Change value
i = 3;
// Wrong type.(C++ is not Python)
i = "Hello"; // Ill-formed
Defining functions
int square(int n)
{
return n*n;
}
auto square(double n)// OK to have two functions with
{ // same name (overloading) as long
return n*n; // as compiler can tell which you
} // mean by context
// The type "auto" means the compiler
int main() { // should perform type inferencing
cout << square(2) + square(3.1416);
return 0;
}
Statically typesafe largely type
inferenced
⚫ The key to implementing lightweight abstractions is
C++’ powerful generic mechanism (also known as
templates).
⚫ Templates let you give a name to a not yet specified
type
⚫ Conceptually, it can often provide the simplicity of
run-time types like in Python together with the safety
of compile-time type validation
⚫ This is one of the major themes in the evolution of
C++ and is still a work in progress
⚫ If you took my Big Data class last fall, this is similar
in many ways to types in Scala
Template functions
template<typename T>
auto square(T n)
{
return n*n;
}
int main()
{
return square(2) + square(3.1416);
}
Containers: vector template
⚫ The vector class in C++ is in fact a template,
so the compiler can build a version optimized
for each class
⚫ vector<int> v = { 1, 2, 3}; // type can be
specified
vector w = {1, 2, 3}; // or deduced also
vector<int>
// loops
for(auto i : v)
std::cout << i << ' '; // Prints 1 2 3
Let’s look at some programs
⚫ hello.cpp, vector_simple_demo.cpp,
frame.cpp, and frame2.cpp from Canvas
⚫ These are adapted from Koenig and Moo’s
Accelerated C++ book
HOMEWORK
HW 1.1
⚫ The purpose of this exercise is to help you make sure you
have a suitable C++ compiler installed and that you know
how to build programs and submit homework
⚫ All referenced code is available on canvas
⚫ Build, compile, and run the "Frame" programs on your
compiler of choice.
⚫ Send something to demonstrate that you’ve done this
successfully (e.g., screenshots, any files you’ve written,
including C++ files, makefiles, Visual Studio project files, a
transcript of your shell session, etc.)
⚫ Do not submit any executable files or large binaries! They
aren’t any good for the graders
HW 1.2
⚫ Print out the first 8 rows of Pascal's triangle.
This assignment is most easily completed by
using a nested container, e.g., a
vector<vector<int>>.
⚫ If you’ve never seen C++ vectors, look at
vector_simple_demo.cpp on Canvas for a
simple example(or ask me or a TA)
HW 1.3 – Extra Credit
⚫ For additional credit on the previous problem,
it should be tastefully formatted. In particular
⚫ Use "brick-wall" formatting, in which the numbers
of each row are presented interleaved with the
numbers on the rows above and below.
⚫ The brick size should bethe maximum size of any
integer in the triangle. For aesthetic as well as
technical reasons, it is useful if the brick size is
odd, so you may increase the size by one if
necessary to make this true.
⚫ Each number should be centered on it's brick.
HW 1.4 (Extra Credit)
⚫ C++ tries to be compatible with C, but it's not
perfect
⚫ Let's see if you can break the compatibility
⚫ Write a valid C program that is not a valid
C++ program.
⚫ Hint: There are ways to do this that don’t
require prior experience with C or C++. Look
for some simple “thinking-outside-of-the-box”
solutions.
HW 1.5 (Extra Credit)
⚫ Why is C++ called C++ and not ++C?
⚫ Note: If you are new to languages with the
“++” operator, see
⚫ http://cplus.about.com/od/glossar1/g/preincdefn.htm
⚫ http://cplus.about.com/od/glossar1/g/preincdefn.htm