ISI seminar at University of Tehran, Department of Mathematics and Computer Science May 2012 90 min.

wakecabbagepatchΛογισμικό & κατασκευή λογ/κού

18 Νοε 2013 (πριν από 3 χρόνια και 9 μήνες)

83 εμφανίσεις

ISI seminar at University of Tehran, Department of Mathematics and Computer Science

May 2012



90 min.

About me …

$ who am i



I have never had a course on C++



Shahid Beheshti university: BA in Software Engineering



Azad university: MA in Software Engineering



13 years of experience in C++ programming



I am the first and only representative of IRAN at C++
standardization committee meetings at


-

Frankfurt (July 2009)


-

Rapperswil (August 2010) and


-

Hawaii (February 2012)

and I paid everything myself.

1998

2003

2011

1999

C++98

C99

C++03

C++11

C++1y

C1x


C++0x = C++11

x = B


C++1y = C++1?

Probably y = 7

C

Simula

1978

1967

Living languages must
change, must adapt, must
grow.




Edward
Finegan


C++ standardization: ISO


2,000,000 <= Number of C++ programmers <= 4,000,000


It’s close to 4,000,000







C
++

is a
general
-
purpose programming language

with a
bias towards
systems programming

that



is a better C



supports data abstraction



supports object
-
oriented programming



supports generic programming

C++ Programming language = The core language + Standard library

www.research.att.com/~bs/applications.html


Wide applications: software Infrastructures, Resource
-
constrained
applications, System software, Embedded systems software, High
-
performance systems, Web services, …

C++ is a multi
-
paradigm
programming language.

C++ is a language not a
complete system.


Make C++ a better language for systems programming and library
building through


Maintain stability and compatibility: with C
99
and C++
98


Increased type safety


Performance improvement


More ability to work directly with hardware: Embedded system
programming and High
-
performance computation





Make C++ easier to teach and learn through


Increased uniformity


More novice supports: better libraries and more general rules


Simplifying simple tasks







Major features of C++
0
x can be categorized:


Object
-
oriented programming


Generic programming


System programming


Machine models, threads and concurrency


Library building





Library building

OOP

GP




Threads and Concurrency

SP


Key concepts:

1.

The power of old and new
features of C++ (C++
98
and
C++
0
x) is boosted when they
are combined together.

2.

A typical feature of C++
0
x
affects on several
entities/areas of ecosystem.

C++
0
x ecosystem

longer integers: long long

removing right
-
angle
brackets problem

C++
0
x core language features

type deduction from
initializer: auto

Range
-
based for
statement

Scoped and Strongly
typed enums: enum
classes

A literal for null pointers:
nullptr

Specifying the type of
an expression:
decltype

Suffix return type
syntax

Variadic templates

Delegating
constructors

Inherited
constructors

Generalization of
Unions and structs
(PODs)

Static (compile
-
time)
assertions:
static_assert

Prevent narrowing

defaulted and
deleted functions

Unicode characters

Raw string literals

Extern templates

Template alias

Local types as
template arguments

Initializers list

Uniform initialization
syntax and semantics

In
-
class member
Initializers

Explicit conversion
operator

C++
0
x core language features

User
-
defined literals

Override controls:
override and final
identifiers

Compatibility with
C
99
features

thread
-
local storage

Inline namespace

Lambda expressions

Preventing exception
propagation:
noexcept

Attributes

R
-
Value reference:
Move semantics

Special member
functions extension:
Move operations

alignment


It’s like a laundry list. Its like a shopping list
and they aren’t interesting by themselves.


A programming language isn’t just a bunch
of features
. A programming language is a
collection of styles.

Generalized and
Guaranteed constant
expressions: constexpr


combination of features in different
context/styles/paradigms is most important
aspect of C++.

New containers: array,
forward list, unordered
containers

Container improvements

C++
0
x standard library features

Threads and
concurrency related
features: threads,
Mutexes, Locks,
Condition variables,


Random number
generations

Algorithm improvements

N
-
tuples: tuples

Various kind of smart
pointers: unique_ptr,
shared_ptr, weak_ptr

Polymorphic function
object wrapper: function

New algorithms: all_of,
any_of, is_sorted, move,
copy_if, iota, …

Futures and Promises

Garbage collection
ABI

Atomics

Asynchronous
operations

Scoped allocators

meta
-
programming
and type traits

binding and function
template bind

Memory model

Time utilities

Regular expressions


The
Maximum Munch

principle


“unsigned long int”

is one token.


“++” is one token.


“>>=“ is one token.



int i =
32
;

i
>>

2
;
// i ==
8

cin
>>

i;
// read from standard input and put to i

vector<list<int
> >

vl
;
// additional space


stack<complex<int
>>

sc;
// error in C++03

vector<list<map<int, string
>>>

vlm
;
// ok in C++0x

template

<


class T

>

class vector {


// …

};

Angle brackets


Compilation phases


Lexical analysis: make tokens


Syntax analysis: check the grammar


Type checking: find the type of names



Lexical analysis

Syntax analysis

Type checking

data types

Built
-
in types

User
-
defined types

C++: Fundamental types

C++
98

char

short

int

long

float

double

long double

bool

wchar_t

char
16
_t

char
32
_t

long long

C++
0
x

long long

too_large = 3000000000000;
// No comment ;)

long long wp = 7000000000;
// World population

int shares = 500000000;
// # shares of a typical symbol at TSE

short price = 4000;
// the closing price of each share in IRR


long long capital = shares * price;
// the corp. capital

long long dataset_size = 16E9;
// typical Facebook dataset size

long long One = 1LL;

char c = ‘x’;
// narrow character, C++98 and C++0x

wchar_t w = L‘x’;
// wide character, C++98 and C++0x

char16_t

c16 = u‘x’;
// at
-
least 16
-
bit character, only C++0x

char32_t

c32 = U‘x’;
// at
-
least 32
-
bit character, only C++0x


A longer integer that’s
at least
64
-
bits.


In
2
’s complement representation:
[
-
2
n
-
1
,
2
n
-
1



1
], n = number of bits


16
-
bit and 32
-
bit characters

char
16
_t

char
32
_t

template <class T> class numeric_limits {

public:


// uninteresting defaults

};

template <> class numeric_limits<long long> {

public:


inline static long long max()


{


return
9223372036854775807
;
// largest value


}


inline static long long min()


{


return
-
9223372036854775808
;
// smallest value



}


// ...

};


<limits> header file

class template

template specialization



Many important things about C
++

fundamental data types like the exact
size of types are
implementation
-
defined
by the standard.

sizeof(char) ==
1

sizeof(long) <= sizeof(long long)

sizeof(long long) >=
8




long long suffix: LL,
ll

const unsigned long long int a =
1
LL
;

const long long int b =
-
2
ll
;


null pointers


C


N
ull pointer constant

// macros

#define NULL 0

#define NULL ((void *)0)

char* p = NULL;


C++
98


N
ull pointer constant

char* p =
0
;
// points to nowhere



// no memory allocation yet


Zero (
0
) is an int.



No object is allocated with the address
0
.
0
acts as a pointer literal,
indicating
that a pointer doesn’t refer to an object.


Problems with NULL and 0:


C++0x


N
ull pointer constants: 0,
nullptr


Distinguishing between null and
zero.


Naming null

char* pc =
0
;

// still good

char* pc
2
= nullptr;
// best

long long x = NULL;
// it works!

long long y =
nullptr
;
// error

void f(int) {
/* … */

}

void f(long long*) {
/* … */

}

f(
nullptr
);

// called f(long long*)

class Point { /* … */ } *pp =
nullptr
;

struct Node {


// Node for double
-
linked list


Node* Next =
nullptr
;


Node* Prev =
nullptr
;

};


Enumerations

enum TrafficLight { RED, YELLOW, GREEN };

enum Color { Red, Green, Blue };

Color c = RED;
// error: two different enumerations

int light = GREEN;
// OK


C99/C++98 style enumerations (conventional)are half
-
baked:


Implicit conversion from enumeration to int


No scope for enumerators


The pre
-
determined underlying type of enumeration: int


C++ 98

enum RGB { RED, GREEN, BLUE };

enum class

TrafficLight { RED, YELLOW, GREEN };

enum class

Color

{ RED, GRENN, BLUE };

enum class

E
: long long
{ E
1
=
1
LL, E
2
=
2
LL };

Color c = Color::RED;

TrafficLight CrossRoad = TrafficLight::RED;

int light = GREEN;
// OK: RGB::GREEN

int light = TrafficLight::GREEN;
// error: TrafficLight
-
>int conversion


C++0x solution: Enumeration classes, the strongly typed
and scoped enumerations


In C++
98
, the programmer must state
the type of variables.

Static languages: Fortran, Algol, C, C++, Java, …

Dynamic languages: Lisp, Python, …

State the
type of
variables
clearly


Deduce the type of
variables with the
assigning values

double g =
9.81
f;
// g is double

int answer =
42.1
;
// answer =
42


Compiler prefers type to initializer.


auto: Type Deduction from Initializer

Run
-
time

Design
-
time

Compile
-
time

Specify types at
design
-
time

C/C++

Deduce types at
compile
-
time from
initializers

C/C++

Deduce types at Run
-
time
based on assignment

Lisp/Python


Third approach: Compiler can figure out the type of expressions at
compile
-
time.

auto

pi =
3.14
;
// pi is double, because
3.14
is double

auto pi_ptr = &pi;

template<class T> T* Factory(T t) { return new T(t); }

auto

clone
1
= Factory(
1
);
// clone
1
: int*

auto clone
2
= Factory(
2.0
f),
// clone
2
: float*

auto clone
3
= Factory(Point(
0
,
0
));
// clone
3
: Point*


Basic examples:


Initialization vs. Assignment

auto big_one = 1LL;
// initialization: big_one is long long forever

big_one = 1UL;
// assignment: big_one is still long long

// the today (opening, closing) prices of symbols at NASDAQ

map<string, pair<double, double
>>

price;

// print the content of map

for (map<string, pair<double, double>>::iterator it =
price.begin();

it != price.end(); ++it) {


cout << it
-
>first << ‘
\
t’ << ‘[‘ << it
-
>second.first




<< ‘,’ << it
-
>second.second << ‘]’ << ‘
\
n’;

}

MSFT

27.56

DELL

28.10

15.16

15.34

ORCL

26.70

26.93


Examples

for (
auto

it = price.begin(); it != price.end(); ++it) {


cout << it
-
>first << ‘
\
t’ << ‘[‘ << it
-
>second.first




<< ‘,’ << it
-
>second.second << ‘]’ << ‘
\
n’;

}

1
.

2
.



auto <variable> = expression

int x =
5
;
// verbose: the int is redundant

auto x =
5
;
// OK: x is int because
5
is int



Conventional general
for

statement: You can do almost anything.

int a[
10
];

for (int i =
0
; i
<=
10
; ++i) {


a[i] = i;

}

void print(list<int>& L)

{


for (list<int>::const_iterator cit = L.begin(); cit != L.end(); ++cit)


cout << *cit << ‘
\
n’;

}


off
-
by one error


Rather verbose


A range for statement allows you to iterate through a "range”.


Range: arrays, containers, initializer lists, and all data structures with
the STL sense


C++0x


using auto

void print(list<int>& L)

{


for (
auto

cit = L.begin(); cit != L.end(); ++cit)


cout << *cit << ‘
\
n’;

}


C++
0
x

One step further: range
-
based for loop


Range
-
based for loop

void print(list<int>& L)

{


for(auto x : L)

cout << x << ’
\
n’;

}

Iterate through the sequence
using
begin

and
end

to find the
sequence's bounds.

Expands to

int a[
10
];

int i =
0
;

for (auto x : a) x = i++;

for (
const auto

x : a) cout << x << ‘
\
n’;


No off
-
by
-
one error


C++
0
x

// C++
98

// initialize map using initializers list: we’ll discuss it too soon.

map<string, int> inventory = { {"Nail",
3000
}, { "Hammer",
10
}, {"Saw",
5
} };

for (auto p = inventory.begin(); p != inventory.end(); ++p) p
-
>second++;

for (auto p = inventory.begin(); p != inventory.end(); ++p)


cout << p
-
>first << '
\
t' << p
-
>second << '
\
n‘;

// C++0x

for (
auto&

item : inventory) item.second++;

for (
const auto&
item : inventory)

cout << item.first << '
\
t' << item.second << '
\
n';


maps


Defaulted and deleted functions


Example: C++ Common idiom: Prohibiting copy operations.

// C++
98

class X {


X(const X&);


X& operator=(const X&);


// use other special member functions


// as default

};

// A typical implementation of singleton

template<class T>

class Singleton {


T t_;
// wrapped element


static Singleton*
pInstance
;


Singleton(
const

T& t = T()) : t_(t) {}


Singleton(const Singleton&) =
delete
;


Singleton& operator=(const Singleton&) =
delete
;

public:


static Singleton* Instance(T t = T()) {


if (!
pInstance
)


pInstance

= new Singleton(t);


return
pInstance
;


}


// other member functions

};

// C++
0
x

class X {
// can’t copy it


X(const X&)
= delete
;


X& operator=(const X&)
= delete
;

public:


X()
= default
;


~X()
= default
;

};

// use_singleton.cpp

template<class T>

Singleton<T>*
Singleton<T>::
pInstance

=
nullptr
;


Singleton<int>* s =
Singleton<int>::Instance();

1.

2
.

class A {


int a =
0
;

};


C++
98


Only
static const members of integral types
can be initialized
in
-
class, and the initializer has to be a constant expression.

class Values {


static const long c =
3
e
8
;
// the light speed


static const float g =
9.81
;
// error: not integral type


const int i =
10
;
// error: not static


static int j =
11
;
// error: not const


static const string s = “”;
// error: no integral type

};


C++0x


You can initialize non
-
static data members.
Often, all
constructors use a common initializer for a member:

class A {


int a;

public:


A() : a(0) {}

};

It’s equivalent to

class FinInst {
// financial instrument


string market = “Dow”;


string symbol;

public:


FinInst() {}


FinInst(string symb) : symbol(symb) {}

};

FinInst Microsoft(“MSFT”), Oracle(“ORCL”);


Example:


If a member is initialized by both an in
-
class
initializer and a constructor, only the constructor's
initialization is done (it "overrides" the default).


In
-
class member initialization

double d;
// for global or static zero
-
initialized, for local no initialization

int i = 10;
// copy initialization

int* ip = &i;
// pointer initialization

char array[] =
{

‘H’, ‘e’, ‘l’, ‘l’, ‘o’
}
;
// array of five characters

struct Point { int x, y; } p =
{

0, 0
}
;
// member
-
wise initialization


C initialization. built
-
in types, pointers and aggregate: array, struct


Initialization is one of the most fundamental concepts in C++.


C++
98
:

class Point { int x, y; } p = {
0
,
0
};
// error in C++
98
: class isn’t aggregate

list<short int> Even = {
0
,
2
,
4
,
6
,
8
};
// error: list isn’t aggregate

set<short int> Odd = {
1
,
3
,
5
,
7
,
9
};
// error: set isn’t aggregate


C++
98
:


Use Constructor


push_back, insert, … operations

class Point {

int x, y;

public:


Point(int xx, int yy) : x(xx), y(yy) {}

};

Point p(
0
,
0
);
// object construction

list<short int> Even;
// empty list

Even.push_back(
0
); Even.push_back(
2
);
// …

set<short int> Odd;
// empty set

Odd.insert(
1
); Odd.insert(
3
);
// …


Initializer lists

Provide
as good support for user
-
defined types as for
built
-
in types
.



C
++

Language
-
technical rule:


Problem: The following rule is broken:

list<short int> Even =
{
0
,
2
,
4
,
6
,
8
}
;

set<short int> Odd =
{
1
,
3
,
5
,
7
,
9
}
;

vector<string> Market =
{
“Dow”, “”Nasdaq”, “S&P
500

}
;

map<string, int> inventory =
{ {
"Nail",
3000
}
,
{
"Hammer",
10
}
,
{
"Saw",
5
} }
;

map<string, pair<double, double>> price = { {“MSFT”, {
27.56
,
28.10
}},

{“DELL”, {
15.16
,
15.34
}}, {“ORCL”, {
26.70
,
26.93
}} };

price.insert
( {“GOOG”, {
659.15
,
650.02
}} );


C++
0
x extends the concept of initializer lists to standard containers.

template<class T>

class std::vector {

public:


// various constructors: default, copy, …


vector(std::initializer_list<T>);

// init
-
list ctor


// …

};


Init
-
list constructor


C++ has always had the concept of
constant expressions
.



const’s primary function is to express the idea that an object is not
modified through an interface.

const

double PI =
3.14
;
// don’t change the content of PI

class Point {


int x, y;

public:


Point(int xx, int
yy
) : x(xx), y(
yy
) {}


int
GetX
()
const

{ return x; }
// constant member function


void
SetX
(int xx) { x = xx; }
// non
-
constant member function


// …

};

const

Point Center(
0
,
0
);
// constant object

void f(
const

Point);
// copy semantics: don’t change the content of argument

// array_bound.c++

int get_five() { return
5
; }

long long LA[
get_five
() +
10
];
// error: array bound is not an integer constant


Two problems:


1
) No
guarantee

for compile
-
time evaluation


2
) No
generalized

constant expressions


Example: Array bound


Generalized and guaranteed constant expressions (constexpr) extends
compile time evaluation to functions and variables of user
-
defined
types.

// array_bound.c++

constexpr

int get_five() { return
5
; }

long long LA[get_five() +
10
];
// OK

fill(LA, LA +
15
,
42
LL);

constexpr

double abs(double x) { return x < 0 ?
-
x : x; }

constexpr

double PI = 3.14;

struct Point {


int x, y;


constexpr

Point(int xx, int
yy
) : x(xx), y(
yy
) {}


constexpr

int
GetX
() const { return x; }

};

int main()

{


constexpr

auto
abs_val
[] = { abs(1.0), abs(2.0), abs(
-
3.14) };


return 0;

}


More examples



constexpr's primary function is to extend the range of what can be
computed at compile time, making such computation type safe.



Rvalue references solve at least two problems:


Implementing move semantics


Perfect forwarding

int i = 42;

int j = i;
// exact copy of i

string s = "I am a string!";

string t = s;
// Make a copy of s: needs memory allocation

vector<string> v1(1000, “foo”);

vector<string> v2 = v1;
// a lot of memory allocation


Value semantic: Copy and assignment


Move semantics is very important feature in library building.

string t = std::
move
(s);
// "Steal" state from s, could invalidate s

Source

Target

Initial state

Final state

Copy

Source

Target

Initial state

Final state

Move

template<class T

void swap(T&
a,
T&
b)

{


const
T temp = a;


a = b
;


b = temp
;

}

template<class T>

void std::swap(T& a, T& b)

{


const T temp = move(a);
// move a into temp


a = move(b);



b = move(temp);

}


Swap


Swapping heavy objects: Images, Matrixes, Datasets, …


Swapping large vector of huge objects


Sorting large containers (sort uses swap operation)


Order of magnitude or more performance gain

// C++
98
:

// Copy operations

// Copy elision, Return Value Optimization

string flip(string s)

{


reverse(
s.begin
(),
s.end
());


return s;

}

// C++
0
x:

// Move operations

string flip(string s)

{


reverse(
s.begin
(),
s.end
());


return s;

}

class X { /* … */ };

X x;

X&
xr

= x; // bind non
-
const reference to l
-
value

const X& xr2 = x; // bin

int i = 0;

int&
ir

= i;
//
ir

is another name for i

ir
++;
// i = 1

long long&
ll_ref
;
//

error: reference should be initialized

long long&
ll_ref

= 1LL;
//
error: reference should be initialized with l
-
value

long long&
ll_ref

= long long(100);
// error: bind to temporary object

Left
Value

Right
Value

a = a * b

Assignment operator


L
-
value vs. R
-
value


L
-
value reference vs. R
-
value reference


A
reference

is an
alternative

name for an
object.

class X {
//
the
empty class

};

class X {

public:


X
() = default;
//
default
constructor


X(const X
&) = default;
//
Copy
Constructor


X(const X
&&
) = default;
// Move constructor


X& operator=(const X
&) = default;
//
copy assignment operator


X& operator=(const X
&&
) = default;
// move assignment operator


~
X
() = default;
//
destructor


// …

};

C++
0
x compiler generates


Move constructor & Move assignment operator


A lambda expression is a mechanism for specifying a function object.



The C++ library offers a number of algorithms that take functions as
arguments.

template<class InputIterator, class T>

InputIterator
find
(InputIterator first, InputIterator last, const T& value);


template<class InputIterator, class Predicate>

InputIterator
find_if
(InputIterator first, InputIterator last, Predicate pred);


template<class InputIterator, class Predicate>

InputIterator
find_if_not
(InputIterator first, InputIterator last, Predicate pred);

1
.

2
.

3
.


Find family

C++98

C++0x


Predicates, Function objects (Functor)


Difficult to write for novices

bool is_multiple_of_function(int a)
// a function predicate

{


return (a %
7
==
0
);

}


class is_multiple_of_functor {
// a function object predicate

public:


bool operator()(int i) { return i %
7
==
0
; }

};


int main()

{


vector<
long long
> v;


for (auto x =
0
, y =
1
; x <
1000000
&& y <
2000000
; ++x, y +=
2
)


v.push_back(x*x +
3
* y
-
2
*x*y +
3
);


auto

d
1
= count_if(v.begin(), v.end(), is_multiple_of_function);


auto

d
2
= count_if(v.begin(), v.end(), is_multiple_of_functor());


auto

d
3
= count_if(v.begin(), v.end(),
[](int i) { return (i %
7
==
0
); }
);


cout << "d
1
= " << d
1
<< '
\
n‘;
// prints d
1
=
146073


cout << "d
2
= " << d
2
<< '
\
n‘;
// prints d
2
=
146073


cout << "d
3
= " << d
3
<< '
\
n';
// prints d
3
=
146073



return
0
;

}

vector<int> v = {50,
-
10, 20,
-
30};

sort(v.begin(), v.end());
// the default sort

// now v should be {
-
30,
-
10, 20, 50 }

1.

2
.


Example 1: Sorting

[](int a, int b) { return abs(a) < abs(b); }

// sort by absolute value

sort(v.begin(), v.end(), [](int a, int b) { return abs(a)<abs(b); });

// now v should be {
-
10
,
20
,
-
30
,
50
}

Capture


Example
2
: Sum and Product

int sum =
0
;

long long product =
1
;

for_each( values.begin(), values.end(),
[&]
(int i){ sum += i; product *= i; });

Class templates

find, find_if , copy, count, sort
random_shuffle, sort, transform

unique , fill, generate, for_each,
remove, reverse, binary_search

set_union, …

Function templates

C++98


~ 60 algorithms

all_of, none_of, any_of, …

C++
0
x


~
30
new
algorithms

vector,


list,

map, set,

multimap, multiset,

stack, queue, deque, string, …

array

forward_list

unordered_map,
unordered_set,
unordered_multimap,
unordered_multiset, …

C++
98


~
12
containers

C++
0
x


~
7
new containers

iterator

C++ Programming language = The core language + Standard library

C/C++ array

C++ vector

begin (iterator)

end (iterator)

...

0

1

2

3

4

C
-
Style Array

Size unaware

Run
-
time
variable size

Dynamic
resize

Implicit decay
name to
pointer

Dynamic
storage

Vector

C++
0
x standard Array container

Pointer
arithmetic

v

a

string a[
3
] = { “One”, Two”, “Three” };

a[
4
] = “Four”; // error

vector<string> v = { “One”, Two”,
“Three” };

v.resize
(
1000000
);

v.shrink_to_fit();


array container



Array is suitable for embedded systems
programming, and similar constrained,
performance
-
critical, or safety critical
tasks.



(Hard) Real
-
time systems, Airplanes, …


hash map containers

map

multimap

set

multiset

unordered_map

unordered_multimap

unordered_set

unordered_multiset


C++
98


C++
0
x

template<class T, int N>

class std::array {


T elem[N];

};

array<int,
10000
> a;

iota(a.begin(), a.end(),
0
);

int* c_array = a.data();

a.fill(a.begin(), a.end(),
0
);

template <class Key, class T,
class Compare = less<Key>
>

class std::map;

template <class Key, class T,

class Hash = hash<Key>
>

class std::unordered_map;


Associative container


Hash map container


Balanced binary tree


Hash table, bucket, Hash function


Data lookup complexity:
O(log n)


Data lookup complexity:


Average:
O(
1
)
, Worst:

O(size())


Huge Phonebook, Large symbol tables in compilers, Huge datasets in
search engines, database indexing …


For larger numbers of elements (e.g. thousands), lookup in an
unordered_map (hash function call) can be much faster than for a
map (comparison).


Hash function quality


Ordered


Un
-
ordered

1. Pointers don’t have the
value semantic.

2
. Pointers don’t have
ownership management.

int i = 0;

int j = i;
// copy

j = i;
// assignment

string s = “A string …”;

string t = s;
// another string

string u;

u = t;
// copy assignment op.


int and std::string have value semantics

char* p = “No value semantics”;

char* q = p;
// p and q point to single data

long long* llp = new long long(
3000000000000
);

long long* llp
2
= llp;

delete llp;

delete llp
2
;
// double deletion catastrophic

42



int* ip = new int(
42
);
//
1
: ip owns the allocated memory

// …

ip =
0
;
//
2
: assign something else to p: lose ownership



//1

//2

ip

ip


the variable ip not only points to, but also
owns, the
memory allocated for the integer object.

Memory
leak


Shallow copy vs. Deep copy

3. The problem about “automatic”
memory management.


new and delete


new [] and delete []

class MyClass {


// …

};


void f()

{


MyClass* p = new MyClass();
// memory allocation


MyClass* pa = new MyClass[
10
];


// …


delete p;

// memory release


delete [] pa;

}

4. No exception safety

X* f()

{


X* p = new X;


// do something


// maybe throw an exception: memory leak


return p;

}


Exception
-
safety: the notion that a program is structured so that
throwing an exception doesn't cause unintended side effects.


typical side
-
effect: Memory leak


RAII: Resource Acquisition is
Initialization


C
-
Style pointers


Raw pointers



Solution: Put raw pointers in a
class and try to mimic their
behaviors.


C++
98
: auto_ptr

// abbreviated and simplified

template<class T> class std::auto_ptr {

private:


T* p;

public:


explicit
auto_ptr(T* p_ = 0)

: p(p_) {}


auto_ptr&
operator=
(const auto_ptr& ap)


{



p = ap.p; ap.p = 0; return *this;


}


auto_ptr(auto_ptr& ap)

:



p(ap.p) { ap.p = 0; }


~auto_ptr()

{ delete p; }


T&
operator*()

const { return *p; }


T*
operator
-
>()

const { return p; }

private:


T* p;

};

1.

void client()

{


auto_ptr<float>



ap(new float(
3.14
));
//
1


// use ap


float f= *ap;



auto_ptr<float> ap
2
= ap;
//
2


// no need to delete auto ptrs

}
// ap
2
and ap are destroyed here

2.

3.14

//
1

//
2

ap

ap2

3.14

p

p

ap

p

Transfer
ownership


C++0x


unique_ptr: Strict ownership


shared_ptr: Shared ownership


weak_ptr: Shared ownership

template<class T> class shared_ptr {


T* p;


long use_count;

};

void test()

{


shared_ptr<int> p1(new int(42));
// count is 1


{


shared_ptr<int> p2(p1);
// count is 2


{


shared_ptr<int> p3(p1);
// count is 3


shared_ptr<int> p4;


p4 = p3;
// count is 4


cout << p1.use_count() << '
\
n'; // print 4


cout << (*p1) << '
\
n'; // print 42


// count goes back down to 2


}


}
// count goes back down to 1

}
// here the count goes to 0 and the int is deleted.

unique_ptr<X> f() {


unique_ptr<X> p(new X);


// …


return p;

}
// the ownership is transferred out of f()


Tuple is one trivial
application of variadic
template

template<class ... Types>
struct std::tuple {
/* … */

};

tuple<> t
0
;
// Types contains no arguments

tuple<int> t
1
;
// Types contains one argument: int

tuple<int, float> t
2
;
// Types contains two arguments: int and
float

list<tuple<string, int, double>> employee;
// result of SQL query

vector<tuple<int, int, int, int>> div_computation;
// division parts


Variadic templates


A
template parameter pack
is a template parameter
that accepts zero or more
template arguments.


Templates

template<typename T>

class Wrapper {


T t;


// …

};


template<typename T
1
, typename T
2
>

struct Pair {


T
1
first;


T
2
second;


// …

};


template<typename T
1
, typename T
2
, typename T
3
>

T
3
multiply(T
1
a, T
2
b)

{


// …

}

#include <iostream>

#include <tuple>

#include <vector>

using namespace std;

vector<int> prime = {
2
,
3
,
5
,
7
,
11
,
13
,
17
,
19
,
23
,
29
,
31
,
37
,
41
,
43
,
47
};

vector<
tuple
<int, int, int>> result;

int main()

{


for (auto i : prime)


result.push_back(
make_tuple
(i, i/
4
, i %
4
));


for (auto i : result)


cout <<
get<
0
>
(i) << '
\
t' <<
get<
1
>
(i) << '
\
t' <<
get<
2
>
(i) << '
\
n';


return
0
;

}


Think deep about the size of program when written in the following
styles:


C++
0
x:
14
lines


C++
98


ARM C++ (around
1990
)


K&R C


Simple computation:


Major issues in thread programming


Memory model and machine model


What is memory location?


Launching threads


Should be very efficient


Thread synchronization

Data races,
Mutual exclusion, …


Atomics


fine
-
grained atomic access, lock
-
free programming
, …


Asynchronous operations


Future + promise


Passing values between threads


Thread safety


A
thread

is …



A thread is a representation of an
execution/computation in a program.


-

Bjarne Stroustrup


A
virtual

CPU


A
lightweight
Process


One process with three threads

C++
0
x approach: Single address space MT

thread


Multicore, Hyper
-
threading, Super
-
threading, Simultaneous Multi
-
threading (SMT), Barrel processors, …


A lot of concurrency models


A C++
0
x program can have more than one
thread of execution
running concurrently.


A C++
98
program had one
thread of execution
.

// C++
98
, Single
-
threaded C++
0
x

#include <iostream>

int main()

{


std::cout << “Hello, world
\
n”;


return
0
;

}

#include <thread>

#include <iostream>

void f()

{


std::cout << “Hello, world
\
n“;

}

int main()

{


std::thread
t(f);


t.
join
();
// “wait for the thread to




// terminate.”


return
0
;

}


A thread is launched by constructing a std::thread with a function.

Single thread: main()

Multithreaded (actually two threads) : main(), t

main

t

join


C++
0
x supports various kind of thread launching.

std::mutex
m;

int sh;
// shared data

// …

m.lock();

// manipulate shared data:

sh +=
1
;

m.unlock();


A
mutex

is a primitive object used for controlling access in a multi
-
threaded system.


Various kind of mutexes: mutex,
recursive_mutex, timed_mutex,
recursive_timed_mutex



A
lock

is an object that holds a reference to a lockable object like
mutex and may unlock it during the lock’s destruction (such as when
leaving block scope).


RAII


Various kind of locks: lock, lock_guard,
unique_lock

mutex m;

int sh;
// shared data

// …

{


std::unique_lock
ul(m);


// manipulate shared data:


sh +=
1
;

}
// lock’s dtor called implicitly

// release mutex m



Condition variables






C++
0
x supports system
-
level concurrency.


There are no standard sophisticated concurrent and thread
-
safe
data structures in C++: STL containers aren’t
thread
-
safe
.


We have to design and implement concurrent data structures from
scratch or use from other proprietary libraries: Visual Studio, Intel
TBB, …


We need higher level libraries for specific forms of concurrent and
parallel programming.


Thinking
concurrently

is hard.


C++
1
y: thread pool, concurrent algorithms, concurrent data
structures, Transactional memory constructs…


C
++

is a
general
-
purpose programming language

with a bias towards
systems programming

and
library building

that



is a better C



supports data abstraction



supports object
-
oriented programming



supports generic programming

C++ is a
multi
-
paradigm

programming language.

C
++

is a suitable tool for implementation of
light
-
weight abstractions

in
“small
-
scale” and
software infrastructure
in

“large scale”.

Software Infrastructure (like OSs, VMs,
Browsers, Embedded systems, …)

Hardware

Application

Application

Application

System programming &


Library building


Light
-
weight abstraction:
compact and efficient data
structures


You don’t have to know every detail of C++ to write good programs.


Focus on programming techniques, not on language features.


The only way to learn a new programming language is by writing programs in
it
.


-

Brian Kernighan & Dennis Ritchie



Programming is understanding
.

-

Kristen
Nygaard


No programming language is perfect.


C++
11
feels like a new language.


International Organization for Standards. Final Draft International Standard
ISO/IEC
JTC
1
SC
22
WG
21
N
3290
. Programming Languages


C++, April
2011
.

http://www.open
-
std.org/jtc
1
/sc
22
/wg
21
/prot/
14882
fdis/n
3290
.pdf


Bjarne Stroustrup. Interview with Debasish Jana for The Computer Society of India:

Part
1
: Paradigm & Philosophy, June
2011
.

Part
2
: Evolution of C++ towards C++
0
x, July
2011
.

Part
3
: C++
0
x Technicalities and Intricacies, August
2011
.

http://www
2
.research.att.com/~bs/interviews.html


Bjarne Stroustrup. C++
0
x FAQ.
2011
,
http://www
2
.research.att.com/~bs/C++
0
xFAQ.html


Andrew Koenig and Barbara Moo.

Part
1
:
4
Useful New Features in C++
0
x.
Dr. Dobb’s
, July
2011
.

Part
2
:
3
Most Useful Library Features of C++
0
x.
Dr. Dobb’s
, August
2011
.

Part
3
: C++
0
x's Tools for Library Authors.
Dr. Dobb’s
, August
2011
.


B. Stroustrup: What is C++
0
x?.
CVu
.
Vol

21
, Issues
4
and
5
.
2009
.
http://www.research.att.com/~bs/what
-
is
-
2009
.pdf


Bjarne Stroustrup: Software Development for Infrastructure. Computer, vol.
45
, no.
1
, pp.
47
-
58
, Jan.
2012
. http://
www
2
.research.att.com/~bs/Computer
-
Jan
12
.pdf


GoingNative

2012
conference. February
2


3
,
2012
Redmond, WA. several seminars
by top C++ experts. https://channel
9
.msdn.com/Events/GoingNative/GoingNative
-
2012
.


Saeed Amrollahi. Modern Programming in New Millennium: A Technical Survey on
Outstanding features of C++
0
x.
Computer Report (Gozaresh
-
e Computer),

No.
199
,
November
2011
(Mehr and Aban
1390
), pages
60
-
82
. (Persian)


Bjarne Stroustrup.
The C
++

Programming Language.
Addison
-
Wesley, Reading, MA,
2000
. special edition.


BoostCon
/C++now!
2012
conference. May
13


18
,
2012
Aspen, Colorado. A lot of
seminars by top C++ experts. http://cppnow.org/overview/


Lang.Next

2012
conference. April
2


4
,
2012
Redmond, WA. A seminar by Herb
Sutter under the title: (Not You Father’s) C++. http://channel
9
.msdn.com/Events/Lang
-
NEXT/Lang
-
NEXT
-
2012
.



C++
11
. Wikipedia. http://en.wikipedia.org/wiki/C%
2
B%
2
B
11
.


Microsoft: Visual C++
2010
, VC
11


GNU: GCC
4.7.0
and GCC
4.8.0



Compilers

Thanks for your patience …