520 likes | 670 Views
A Brief Overview on Outstanding Features of new Revision of C++. C++0x . Saeed Amrollahi www.saeedamrollahi.com. ISI seminar at University of Tehran, Department of Mathematics and Computer Science May 2012 90 min. About me …. $ who am i.
E N D
A Brief Overview on Outstanding Features of new Revision of C++ C++0x Saeed Amrollahi www.saeedamrollahi.com ISI seminar at University of Tehran, Department of Mathematics and Computer Science May 2012 90 min.
About me … $ who am i • Shahid Beheshti university: BA in Software Engineering • Azad university: MA in Software Engineering • 13 years of experience in C++ programming • I have never had a course on C++ • 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.
Living languages must change, must adapt, must grow. – Edward Finegan C++0x roadmap • 2,000,000 <= Number of C++ programmers <= 4,000,000 • It’s close to 4,000,000 C C99 C1x Simula C++98 C++03 C++11 C++1y 2011 1999 1967 1978 1998 2003 • C++ standardization: ISO • C++0x = C++11 x = B • C++1y = C++1? Probably y = 7
C++: A definition-1998 • is a better C • C++ is a general-purpose programming language with a bias towards systems programming that • supports data abstraction • supports object-oriented programming • supports generic programming C++ is a language not a complete system. C++ is a multi-paradigm programming language. C++ Programming language = The core language + Standard library • Wide applications: software Infrastructures, Resource-constrained applications, System software, Embedded systems software, High-performance systems, Web services, … www.research.att.com/~bs/applications.html
C++0x general aims 1 • Make C++ a better language for systems programming and library building through • Maintain stability and compatibility: with C99 and C++98 • Increased type safety • Performance improvement • More ability to work directly with hardware: Embedded system programming and High-performance computation • … 2 • Make C++ easier to teach and learn through • Increased uniformity • More novice supports: better libraries and more general rules • Simplifying simple tasks • …
C++0x general aims cont. • Major features of C++0x can be categorized: • Object-oriented programming • Generic programming • System programming • Machine models, threads and concurrency • Library building GP OOP • Key concepts: • The power of old and new features of C++ (C++98 and C++0x) is boosted when they are combined together. • A typical feature of C++0x affects on several entities/areas of ecosystem. Library building SP Threads and Concurrency C++0x ecosystem
C++0x core language features removing right-angle brackets problem Extern templates Initializers list Local types as template arguments Prevent narrowing longer integers: long long Uniform initialization syntax and semantics Unicode characters In-class member Initializers Static (compile-time) assertions: static_assert Raw string literals defaulted and deleted functions A literal for null pointers: nullptr Inherited constructors Variadic templates type deduction from initializer: auto Suffix return type syntax Delegating constructors Range-based for statement Specifying the type of an expression: decltype Explicit conversion operator Scoped and Strongly typed enums: enum classes Generalization of Unions and structs (PODs) Template alias
C++0x core language features Special member functions extension: Move operations Generalized and Guaranteed constant expressions: constexpr Override controls: override and final identifiers Inline namespace alignment thread-local storage User-defined literals • It’s like a laundry list. Its like a shopping list and they aren’t interesting by themselves. R-Value reference: Move semantics • A programming language isn’t just a bunch of features. A programming language is a collection of styles. Lambda expressions Preventing exception propagation: noexcept • combination of features in different context/styles/paradigms is most important aspect of C++. Attributes Compatibility with C99 features
C++0x standard library features Threads and concurrency related features: threads, Mutexes, Locks, Condition variables, … New containers: array, forward list, unordered containers meta-programming and type traits Time utilities Container improvements Regular expressions New algorithms: all_of, any_of, is_sorted, move, copy_if, iota, … Futures and Promises Random number generations Asynchronous operations Algorithm improvements Atomics N-tuples: tuples Memory model Scoped allocators Various kind of smart pointers: unique_ptr, shared_ptr, weak_ptr Polymorphic function object wrapper: function binding and function template bind Garbage collection ABI
Removing right-angle brackets problem int i = 32; i >> 2; // i == 8 cin >> i; // read from standard input and put to i template < class T > class vector { // … }; • The Maximum Munch principle • “unsigned long int”is one token. • “++” is one token. • “>>=“ is one token. Angle brackets vector<list<int> >vl; // additional space stack<complex<int>> sc; // error in C++03 vector<list<map<int, string>>>vlm; // ok in C++0x Lexical analysis Syntax analysis • Compilation phases • Lexical analysis: make tokens • Syntax analysis: check the grammar • Type checking: find the type of names Type checking
Extending fundamental data types: Longer integers and Unicode characters Built-in types C++: Fundamental types data types bool User-defined types char16_t char wchar_t short int char32_t • A longer integer that’s at least 64-bits. long float double long long long double • In 2’s complement representation: [-2n-1, 2n-1 – 1], n = number of bits C++98 C++0x • 16-bit and 32-bit characters long longtoo_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 char16_t char32_t
long long 2 • Many important things about C++ fundamental data types like the exact size of types are implementation-defined by the standard. class template sizeof(char) == 1 sizeof(long) <= sizeof(long long) sizeof(long long) >= 8 … • <limits> header file template <class T> class numeric_limits { public: // uninteresting defaults }; template specialization 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 } // ... }; const unsigned long long int a = 1LL; const long long int b = -2ll; • long long suffix: LL, ll
Increased type safety • null pointers // macros #define NULL 0 #define NULL ((void *)0) char* p = NULL; • C Null pointer constant • Problems with NULL and 0: • C++98 Null 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. char* pc = 0;// still good char* pc2 = 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; }; • Distinguishing between null and zero. • Naming null • C++0x Null pointer constants: 0, nullptr
Increased type safety • Enumerations • 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 TrafficLight { RED, YELLOW, GREEN }; enum Color { Red, Green, Blue }; Color c = RED; // error: two different enumerations int light = GREEN; // OK • C++0x solution: Enumeration classes, the strongly typed and scoped enumerations enum RGB { RED, GREEN, BLUE }; enum class TrafficLight { RED, YELLOW, GREEN }; enum class Color{ RED, GRENN, BLUE }; enum classE : long long { E1 = 1LL, E2 = 2LL }; Color c = Color::RED; TrafficLight CrossRoad = TrafficLight::RED; int light = GREEN; // OK: RGB::GREEN int light = TrafficLight::GREEN; // error: TrafficLight->int conversion
Increased type safety • auto: Type Deduction from Initializer Static languages: Fortran, Algol, C, C++, Java, … State the type of variables clearly Dynamic languages: Lisp, Python, … Deduce the type of variables with the assigning values • In C++98, the programmer must state the type of variables. • Compiler prefers type to initializer. double g = 9.81f; // g is double int answer = 42.1; // answer = 42 • Third approach: Compiler can figure out the type of expressions at compile-time. Design-time Compile-time Run-time Deduce types at compile-time from initializers C/C++ Specify types at design-time C/C++ Deduce types at Run-time based on assignment Lisp/Python
Using auto auto <variable> = expression int x = 5; // verbose: the int is redundant auto x = 5; // OK: x is int because 5 is int • Basic examples: auto pi = 3.14; // pi is double, because 3.14 is double auto pi_ptr = π template<class T> T* Factory(T t) { return new T(t); } auto clone1 = Factory(1); // clone1: int* auto clone2 = Factory(2.0f), // clone2: float* auto clone3 = Factory(Point(0, 0)); // clone3: Point* • Initialization vs. Assignment auto big_one = 1LL; // initialization: big_one is long long forever big_one = 1UL; // assignment: big_one is still long long 1. • Examples // 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 28.10 DELL 15.16 15.34 ORCL 26.70 26.93 2. … for (auto it = price.begin(); it != price.end(); ++it) { cout << it->first << ‘\t’ << ‘[‘ << it->second.first << ‘,’ << it->second.second << ‘]’ << ‘\n’; }
Simplifying simple tasks • Range-based for loop • Conventional general for statement: You can do almost anything. • off-by one error int a[10]; for (int i = 0; i <=10; ++i) { a[i] = i; } • Rather verbose void print(list<int>& L) { for (list<int>::const_iterator cit = L.begin(); cit != L.end(); ++cit) cout << *cit << ‘\n’; } • A range for statement allows you to iterate through a "range”. • Range: arrays, containers, initializer lists, and all data structures with the STL sense void print(list<int>& L) { for (auto cit = L.begin(); cit != L.end(); ++cit) cout << *cit << ‘\n’; } • C++0x using auto • C++0x One step further: range-based for loop
Simplifying simple tasks • C++0x void print(list<int>& L) { for(auto x : L)cout << x << ’\n’; } Expands to • No off-by-one error Iterate through the sequence using begin and end to find the sequence's bounds. int a[10]; int i = 0; for (auto x : a) x = i++; for (const autox : a) cout << x << ‘\n’; • maps // 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';
Simplifying simple tasks • Defaulted and deleted functions // C++98 class X { X(const X&); X& operator=(const X&); // use other special member functions // as default }; • Example: C++ Common idiom: Prohibiting copy operations. // C++0x class X { // can’t copy it X(const X&) = delete; X& operator=(const X&) = delete; public: X() = default; ~X() = 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 }; 1. 2. // use_singleton.cpp template<class T> Singleton<T>* Singleton<T>::pInstance = nullptr; Singleton<int>* s = Singleton<int>::Instance();
In-class member initialization • 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 = 3e8; // 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: • Example: class FinInst { // financial instrument string market = “Dow”; string symbol; public: FinInst() {} FinInst(string symb) : symbol(symb) {} }; FinInst Microsoft(“MSFT”), Oracle(“ORCL”); class A { int a = 0; }; It’s equivalent to class A { int a; public: A() : a(0) {} }; • 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).
Increased uniformity • Initializer lists • Initialization is one of the most fundamental concepts in C++. • C initialization. built-in types, pointers and aggregate: array, struct • C++98: 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 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 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); // … • C++98: • Use Constructor • push_back, insert, … operations
Increased uniformity • Problem: The following rule is broken: • C++ Language-technical rule: Provide as good support for user-defined types as for built-in types. • C++0x extends the concept of initializer lists to standard containers. 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}} ); • Init-list constructor template<class T> class std::vector { public: // various constructors: default, copy, … vector(std::initializer_list<T>);// init-list ctor // … };
Constant expressions • C++ has always had the concept of constant expressions. 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 • const’s primary function is to express the idea that an object is not modified through an interface. • Two problems: • 1) No guarantee for compile-time evaluation • 2) No generalized constant expressions • Example: Array bound // array_bound.c++ int get_five() { return 5; } long long LA[get_five() + 10]; // error: array bound is not an integer constant
Generalized and guaranteed constant expressions • 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, 42LL); • More examples 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() { constexprauto abs_val[] = { abs(1.0), abs(2.0), abs(-3.14) }; return 0; } • constexpr's primary function is to extend the range of what can be computed at compile time, making such computation type safe.
Move semantics • Move semantics is very important feature in library building. • Rvalue references solve at least two problems: • Implementing move semantics • Perfect forwarding • Value semantic: Copy and assignment 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 string t = std::move(s); // "Steal" state from s, could invalidate s Move Copy Target Source VS. Target Source Initial state Initial state Final state Final state
Move semantics cont. • Swap 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); } VS. template<class T void swap(T& a, T& b) { const T temp = a; a = b; b = temp; } • 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++0x: // Move operations string flip(string s) { reverse(s.begin(), s.end()); return s; }
Move semantics implementation: R-value reference • L-value vs. R-value Right Value Left Value • L-value reference vs. R-value reference a = a * b • A referenceis an alternative name for an object. Assignment operator 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
Move operations • Move constructor & Move assignment operator class X { // the empty class }; C++0x compiler generates 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 // … };
Predicates, function objects, generic algorithms • The C++ library offers a number of algorithms that take functions as arguments. • Find family • A lambda expression is a mechanism for specifying a function object. 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. C++0x C++98 • Predicates, Function objects (Functor) Difficult to write for novices
Lambda expressions: An example 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 d1 = count_if(v.begin(), v.end(), is_multiple_of_function); auto d2 = count_if(v.begin(), v.end(), is_multiple_of_functor()); auto d3 = count_if(v.begin(), v.end(), [](int i) { return (i % 7 == 0); }); cout << "d1 = " << d1 << '\n‘; // prints d1 = 146073 cout << "d2 = " << d2 << '\n‘; // prints d2 = 146073 cout << "d3 = " << d3 << '\n'; // prints d3 = 146073 return 0; }
Lambda expressions: more examples • Example 1: Sorting 1. vector<int> v = {50, -10, 20, -30}; sort(v.begin(), v.end()); // the default sort // now v should be { -30, -10, 20, 50 } 2. [](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; });
STL architecture C++ Programming language = The core language + Standard library Class templates Function templates find, find_if , copy, count, sort random_shuffle, sort, transform unique , fill, generate, for_each, remove, reverse, binary_search set_union, … vector, list, map, set, multimap, multiset, stack, queue, deque, string, … iterator all_of, none_of, any_of, … array forward_list unordered_map, unordered_set, unordered_multimap, unordered_multiset, … C++0x ~30 new algorithms C++98 ~ 12 containers C++98 ~ 60 algorithms C++0x ~7 new containers
New containers • array container begin (iterator) end (iterator) C++ vector C/C++ array v ... a 0 1 2 3 4 vector<string> v = { “One”, Two”, “Three” }; v.resize(1000000); v.shrink_to_fit(); string a[3] = { “One”, Two”, “Three” }; a[4] = “Four”; // error C-Style Array Vector Size aware Compile-time static size Run-time variable size Pointer arithmetic Random-access iterator automatic storage Dynamic resize Size unaware No implicit decay name to pointer Implicit decay name to pointer Dynamic storage No dynamic resize C++0x standard Array container
New containers • Array is suitable for embedded systems programming, and similar constrained, performance-critical, or safety critical tasks. • (Hard) Real-time systems, Airplanes, … 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); • hash map containers • C++0x • C++98 map multimap set multiset unordered_map unordered_multimap unordered_set unordered_multiset
New containers 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 • Un-ordered • Ordered • Data lookup complexity: • Average: O(1), Worst: O(size()) • Data lookup complexity: O(log n) • 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 • Huge Phonebook, Large symbol tables in compilers, Huge datasets in search engines, database indexing …
C-Style pointers problems 1. Pointers don’t have the value semantic. • int and std::string have value semantics 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. char* p = “No value semantics”; char* q = p; // p and q point to single data long long* llp = new long long(3000000000000); long long* llp2 = llp; delete llp; delete llp2; // double deletion catastrophic //1 42 • Shallow copy vs. Deep copy ip //2 2. Pointers don’t have ownership management. int* ip = new int(42); // 1: ip owns the allocated memory // … ip = 0; // 2: assign something else to p: lose ownership ip Memory leak • the variable ip not only points to, but also owns, the memory allocated for the integer object.
C-Style pointers problems cont. 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 • 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 X* f() { X* p = new X; // do something // maybe throw an exception: memory leak return p; } • RAII: Resource Acquisition is Initialization
Raw pointers vs. smart pointers • C-Style pointers Raw pointers 1. • Solution: Put raw pointers in a class and try to mimic their behaviors. // 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; }; • C++98: auto_ptr 2. void client() { auto_ptr<float> ap(new float(3.14)); // 1 // use ap float f= *ap; auto_ptr<float> ap2 = ap; // 2 // no need to delete auto ptrs } // ap2 and ap are destroyed here //1 p 3.14 ap //2 p 3.14 Transfer ownership ap2 p ap
Smart pointers in C++0x • C++0x • unique_ptr: Strict ownership • shared_ptr: Shared ownership • weak_ptr: Shared ownership unique_ptr<X> f() { unique_ptr<X> p(new X); // … return p; } // the ownership is transferred out of f() 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.
Variadic templates and Tuples • Templates template<typename T> class Wrapper { T t; // … }; template<typename T1, typename T2> struct Pair { T1 first; T2 second; // … }; template<typename T1, typename T2, typename T3> T3 multiply(T1 a, T2 b) { // … } • Variadic templates • A template parameter pack is a template parameter that accepts zero or more template arguments. • Tuple is one trivial application of variadic template template<class ... Types> struct std::tuple { /* … */ }; tuple<> t0; // Types contains no arguments tuple<int> t1; // Types contains one argument: int tuple<int, float> t2; // 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
Tuples: A complete example • Simple computation: #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++0x: 14 lines • C++98 • ARM C++ (around 1990) • K&R C
Threads and Multi-threaded programming • Multicore, Hyper-threading, Super-threading, Simultaneous Multi-threading (SMT), Barrel processors, … A lot of concurrency models • 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 … thread • A lightweight Process • A virtualCPU • A thread is a representation of an execution/computation in a program. • - Bjarne Stroustrup One process with three threads C++0x approach: Single address space MT
Simple threads in C++0x • A C++98 program had one thread of execution. But • A C++0x program can have more than one thread of execution running concurrently. • A thread is launched by constructing a std::thread with a function. #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; } // C++98, Single-threaded C++0x #include <iostream> int main() { std::cout << “Hello, world\n”; return 0; } Single thread: main() main t Multithreaded (actually two threads) : main(), t join • C++0x supports various kind of thread launching.
Threads synchronization • A mutex is a primitive object used for controlling access in a multi-threaded system. std::mutex m; int sh; // shared data // … m.lock(); // manipulate shared data: sh += 1; m.unlock(); • 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 mutex m; int sh; // shared data // … { std::unique_lock ul(m); // manipulate shared data: sh += 1; } // lock’s dtor called implicitly // release mutex m • Various kind of locks: lock, lock_guard, unique_lock • Condition variables • …
Concurrent programming: problems • C++0x 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++1y: thread pool, concurrent algorithms, concurrent data structures, Transactional memory constructs…
C++: A definition-2012 • C++ is a general-purpose programming language with a bias towards systems programming and library building that • is a better C • supports data abstraction C++ is a multi-paradigm programming language. • supports object-oriented programming • supports generic programming • C++ is a suitable tool for implementation of light-weight abstractions in “small-scale” and software infrastructure in “large scale”. • Light-weight abstraction: compact and efficient data structures Application Application Application Software Infrastructure (like OSs, VMs, Browsers, Embedded systems, …) System programming & Library building Hardware
Suggestions and Recommendations • 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. • Focus on programming techniques, not on language features. • C++11 feels like a new language. • You don’t have to know every detail of C++ to write good programs.
References and further readings • International Organization for Standards. Final Draft International Standard ISO/IEC JTC1 SC22 WG21 N3290. Programming Languages — C++, April 2011. • http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/n3290.pdf • Bjarne Stroustrup. C++0x FAQ. 2011, http://www2.research.att.com/~bs/C++0xFAQ.html • B. Stroustrup: What is C++0x?. CVu. Vol 21, Issues 4 and 5. 2009. http://www.research.att.com/~bs/what-is-2009.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++0x, July 2011. • Part 3: C++0x Technicalities and Intricacies, August 2011. • http://www2.research.att.com/~bs/interviews.html • Andrew Koenig and Barbara Moo. • Part 1: 4 Useful New Features in C++0x. Dr. Dobb’s, July 2011. • Part 2: 3 Most Useful Library Features of C++0x. Dr. Dobb’s, August 2011. • Part 3: C++0x's Tools for Library Authors. Dr. Dobb’s, August 2011. • Bjarne Stroustrup: Software Development for Infrastructure. Computer, vol. 45, no. 1, pp. 47-58, Jan. 2012. http:// www2.research.att.com/~bs/Computer-Jan12.pdf
References and further readings • Saeed Amrollahi. Modern Programming in New Millennium: A Technical Survey on Outstanding features of C++0x. Computer Report (Gozaresh-e Computer), No.199, November 2011 (Mehr and Aban 1390), pages 60-82. (Persian) • C++11. Wikipedia. http://en.wikipedia.org/wiki/C%2B%2B11. • Bjarne Stroustrup. The C++ Programming Language. Addison-Wesley, Reading, MA, 2000. special edition. • GoingNative 2012 conference. February 2 – 3, 2012 Redmond, WA. several seminars by top C++ experts. https://channel9.msdn.com/Events/GoingNative/GoingNative-2012. • 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://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012. • Compilers • GNU: GCC 4.7.0 and GCC 4.8.0 • Microsoft: Visual C++ 2010, VC11