30

Modern C++

Embed Size (px)

DESCRIPTION

Presentation with a brief history of C, C++ and their ancestors along with an introduction to latest version C++11 and futures such as C++17. The presentation covers applications that use C++, C++11 compilers such as LLVM/Clang, some of the new language features in C++11 and C++17 and examples of modern idioms such as the new form compressions, initializer lists, lambdas, compile time type identification, improved memory management and improved standard library (threads, math, random, chrono, etc). (less == more) || (more == more)

Citation preview

Page 1: Modern C++
Page 2: Modern C++

Modern C++(less == more) || (more == more)

!mailto:[email protected]

Page 3: Modern C++

History

1950 1960 1970 1980 1990 2000 2010 2020

1958!!ALGOL!58!!(Bauer,(Backus(et(al)

1957!!FORTRAN!!(John(Backus)

1969!!C!!(Dennis(Ritchie)

1968!!ALGOL!68

1966!!FORTRAN!66

1983!!AT&T!C++!/!Cfront!!(Bjarne(Stroustrup)

1981!!Objec:ve<C!!(Brad(Cox(and(Tom(Love)

1979!!C!with!Classes!!(Bjarne(Stroustrup)

1978!!K&R!C!!(Brian(Kernighan(and(Dennis(Ritchie)

1977!!FORTRAN!77

1989!!ANSI/ISO!C89

1987!!GNU!C!Released

1999!ISO!C99

1998!!ISO!C++98

2003!!ISO!C++03

2011!!ISO!C++11

2014!!ISO!C++14

2017!!ISO!C++17

2008!!Clang!Released2008!!ISO!C++!TR1

Page 4: Modern C++

What is C++?• A general purpose programming language • Has a strong bias towards systems programming • One layer above assembly language • Multi-paradigm language

• Imperative (C99 superset) • Object-oriented (polymorphism, inheritance) • Functional (immutability, lambdas, currying) • Meta-programming (templates, algorithms)

int do_rdrand() { int r; asm("retry: rdrand eax\n” " jnc retry;\n" : "=a" (r)); return r; }

Page 5: Modern C++

Why C++• ISO/IEC 14882:2011

• International standards organisation represented by national bodies from 164 member countries

• Not open to manipulation by individuals or corporations for proprietary control

• COBOL, Fortran, Ada, Prolog, C, C++, Forth, ECMAscript

• C++ is a software engineering language that enables the production of high performance type-safe, statically verifiable native software.

Page 6: Modern C++

Why C++• C++ is popular

Source: http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

Page 7: Modern C++

C++ projects• GNU Compiler Collection, LLVM, Clang • Java Virtual Machine, Dart, V8, Facebook HHVM • Webkit, Chrome, Safari, Firefox, Internet Explorer • MySQL, LevelDB, MongoDB, SAP DB • Adobe, Autodesk, Apple, Microsoft, … • Scientific computing, Computer Aided Engineering,

Operations Research, Telecommunications, … • Bitcoin ☺

Page 8: Modern C++

What is Modern C++?• Modern C++!

• feels like “a new language” (Bjarne Stroustrup) • C++11 refines the C++ language in a backwards

compatible way to support existing C++ code while enabling simpler and more modern idioms

• Pass-by-value everywhere • STL containers got smarter with r-value references

• Lambdas, initializer lists, variadic templates, etc • Improved memory management • Improved standard library

Page 9: Modern C++

Less is exponentially more“I was asked a few weeks ago, "What was the biggest surprise you encountered rolling out Go?" I knew the answer instantly: Although we expected C++ programmers to see Go as an alternative, instead most Go programmers come from languages like Python and Ruby. Very few come from C++. We—Ken, Robert and myself—were C++ programmers when we designed a new language to solve the problems that we thought needed to be solved for the kind of software we wrote. It seems almost paradoxical that other C++ programmers don't seem to care.” –Rob Pikehttp://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html

Page 10: Modern C++

C++11 has got more

auto lambda

<random>

<type_traits>

<memory>

std::shared_ptr <thread> constexpr

decltype

<mutex> <regex>

std::tuple

std::unordered_set

std::unordered_map nullptr

static_assert <atomic>

std::unique_ptr

std::async

std::future

<functional>

<chrono>

Page 11: Modern C++

C++11 has got less #include <iostream> #include <vector> ! using namespace std; ! int main() { vector<int> v; v.push_back(2); v.push_back(3); v.push_back(5); v.push_back(7); vector<int>::iterator i; for (i = v.begin(); i != v.end(); i++) { cout << *i << endl; } }

#include <iostream> #include <vector> ! using namespace std; ! int main() { vector<int> v = {2,3,5,7}; for (auto a : v) { cout << a << endl; } }

C++98 C++11

int main() { for (auto a : {2,3,5,7}) cout << a << endl; }

or even less

Page 12: Modern C++

Template Metaprogramming• The C++ template system is turing complete at compile time

#include <iostream> // http://stackoverflow.com/questions/3082113/calculating-factorial-using-template-meta-programming ! using namespace std; ! template <int N> struct Factorial { enum { value = N * Factorial<N - 1>::value }; }; ! template <> struct Factorial<0> { enum { value = 1 }; }; ! int main() { cout << Factorial<4>::value << endl; cout << Factorial<0>::value << endl; }

Page 13: Modern C++

Zero-copy layoutOO Language C++11 class Price { int timestamp; int volume; double price; Price(int timestamp, int volume, double price) { this.timestamp = timestamp; this.volume = volume; this.price = price; } static void main(String args[]) { ArrayList<Price> prices; prices.ensureCapacity(4); prices.add(new Price(1307725482, 5, 26.05)); prices.add(new Price(1307725483, 40, 26.15)); prices.add(new Price(1307725493, 100, 26.1499)); prices.add(new Price(1307725493, 112, 26.15)); } }

struct Price { int timestamp; int volume; double price; Price(int timestamp, int volume, double price) : timestamp(timestamp), volume(volume), price(price) {} }; ! int main() { vector<Price> prices; prices.reserve(4); prices.emplace_back(1307725482, 5, 26.05); prices.emplace_back(1307725483, 40, 26.15); prices.emplace_back(1307725493, 100, 26.1499); prices.emplace_back(1307725493, 112, 26.15); }

• Containers use polymorphism and type erase • Need to devolve to structure of primitive arrays

to get reasonable performance, but SoA hasbad cache behaviour

• Looks are deceiving • Templates instantiate optimized code for the type • Superset - allows implementation of polymorphic

containers i.e. vector<object>

Page 14: Modern C++

Zero-copy layoutOO Language - 176 bytes, 5 allocations

C++11 - 72 bytes, 2 allocations

length

array object reference

Opaque Object Header (16-bytes)

64-bit Object Reference (8-bytes) 64-bit Object Reference (8-bytes) 64-bit Object Reference (8-bytes)

Opaque Object Header (16-bytes)

Opaque Object Header (16-bytes)

1307725482 5 26.05

1307725483 40 26.15

1307725493 100 26.1499

Opaque Object Header (16-bytes) size

Opaque Object Header (16-bytes)

1307725482 5 26.05 1307725483 40 26.15 1307725493 100 26.1499

array ptr size capacity

Page 15: Modern C++

No more leaks• std::unique_ptr

• Singleton pointer wrapper • Ensures a single copy of an object • No performance overhead • Automatic release (no more delete)

• std::shared_ptr • Reference counting pointer wrapper • Thread-safe reference counter • Acts like a normal pointer but has overhead • Use when correctness is more important than performance • Automatic release (no more delete)

Page 16: Modern C++

R-value references• template<typename T> void foo(T&&)

• New signature to detect r-values (temporaries) • In a nut shell enables compile time detection of

r-value temporaries (versus l-values) to implement efficientzero-copy move semantics and perfect forwarding

• What is an r-value?

• Adds complexity to hide complexity • Feature designed for STL and library writers • std::forward, std::move

• Efficient pass by value and return by value for containers • Simplifies idiom of user code

vector<Price> raise(vector<Price> prices) { /* does something */ }

raise({Price(1307725482, 5, 26.05), Price(1307725483, 40, 26.15)});

Page 17: Modern C++

Initializer lists • Array initialization

was a C++98 bugbear • Adds new initializer syntax

foo{1,2,3,4} • Can be used in constructor

member initialization • New header

<initializer_list> • New template

initializer_list<T>

struct myclass { myclass (int,int); myclass (initializer_list<int>); /* definitions ... */ }; ! myclass foo {10,20}; // calls initializer_list ctor myclass bar (10,20); // calls first constructor

template <typename T> struct vec { vec(T x) : m{x, 0, 0, 1} {} vec(T x, T y) : m{x, y, 0, 1} {} vec(T x, T y, T z) : m{x, y, z, 1} {} vec(T x, T y, T z, T w) : m{x, y, z, w} {} T m[4]; }; ! vec<float> a(1, 2, 3);

Page 18: Modern C++

Delegating constructors• Really. C++98 didn’t have them

template <typename T> struct vec { vec(T x) : vec(x, 0, 0, 1) {} vec(T x, T y) : vec(x, y, 0, 1) {} vec(T x, T y, T z) : vec(x, y, z, 1) {} vec(T x, T y, T z, T w) : m{x, y, z, w} {} T m[4]; };

Page 19: Modern C++

Threads and Futures

• std::thread • std::async • std::future • C++ is in now line

with other modern languages threadcapabilities

#include <iostream> #include <vector> #include <algorithm> #include <numeric> #include <future> ! // source http://en.cppreference.com/w/cpp/thread/async ! template <typename I> int parallel_sum(I beg, I end) { typename I::difference_type len = end - beg; if (len < 1000) { return std::accumulate(beg, end, 0); } I mid = beg + len/2; auto handle = std::async(std::launch::async, parallel_sum<I>, mid, end); int sum = parallel_sum(beg, mid); return sum + handle.get(); } ! int main() { std::vector<int> v(10000, 1); std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << ‘\n'; }

Page 20: Modern C++

Compile-time type identification• New header <type_traits> • std::is_void<T> • std::is_integral<T> • std::is_array<T> • std::is_class<T> • std::is_pointer<T> • std::is_volatile<T> • std::rank<T>, std::extent<T,N> • …. many many more ….

template <typename R> static const EGType& typeOf() { typedef typename std::remove_extent<R>::type A; typedef typename std::remove_pointer<R>::type P; if (std::is_array<R>::value) { typedef typename std::remove_const<A>::type V; return arrayType<V>(); } else if (std::is_pointer<R>::value) { typedef typename std::remove_const<P>::type V; return pointerType<V>(); } else { typedef typename std::remove_const<R>::type V; return integralType<V>(); } }

Page 21: Modern C++

Variadic templates• Variadic templates allow

implementation of a compile time type safe printf(…)

• Variadic templates combined with compile time type identification gives super powers to C++

• Can collect type information at compile time and use at runtime

• Allows creation of an Objective-C style messaging system with late-binding

#include <type_traits> #include <functional> #include <string> #include <iostream> #include <iomanip> ! using namespace std; using namespace std::placeholders; ! template<typename T> void reflect_compiler_reflect(T value) { cout << setw(70) << typeid(T).name() << " is_pointer=" << is_pointer<T>::value << " is_integral=" << is_integral<T>::value << " is_floating_point=" << is_floating_point<T>::value << " is_class=" << is_class<T>::value << " is_empty=" << is_empty<T>::value << endl; } ! template<typename T, typename... Args> void reflect_compiler_reflect(T value, Args... args) { reflect_compiler_reflect(value); reflect_compiler_reflect(args...); } ! int main() { int a = 1; float b = 4.5f; double c[71]; string d; auto e = [] (int a) {}; auto f = std::bind(e, 99, _1); struct {} g; reflect_compiler_reflect(a, b, c, d, e, f, g); }

Page 22: Modern C++

User-defined literals• Allow definition of type

safe SI units and other creative uses

• Solve Mars Climate Orbiter type problems class Symbol { public: string name; Symbol(const char *name) : name(name) {} }; ! Symbol operator "" _symbol(const char* name, size_t) { return Symbol(name); } ! int main() { Symbol Foo = "Foo"_symbol; }

Page 23: Modern C++

More functional• lambdas

• [], [=], [&] • use in place of old-style function objects • combine with existing STL generic algorithms

e.g. std::partition • currying

• std::function • std::bind • std::placeholders::_1

Page 24: Modern C++

Lots more STL• Compile time reflection

• <type_traits> • Containers

• <array>, <unordered_set>, <unordered_map>, <forward_list> • Multi-threading

• <atomic>, <thread>, <mutex>, <future>, <condition_variable> • More utility

• <tuple>, <regex>, <chrono>, <codecvt> • Numerics

• <random>, <ratio>, <cfenv>

Page 25: Modern C++

C++14

• Generic lambdas • lambda initializers • Variable templates • make_unique • Runtime sized arrays • Filesystem (Boost::filesystem) • Networking

auto lambda = [](auto x, auto y) {return x + y;};

auto lambda = [value = 1] {return value;};

template<typename T> constexpr T pi = T(3.1415926535897932385);

auto u = make_unique<some_type>(ctor, params);

void foo(size_t n) { int a[n]; }

Page 26: Modern C++

LLVM / Clang• Modular compiler toolchain • 2012 ACM Software System Award • Clang memory sanitizer • Clang address sanitizer • Clang thread sanitizer • Clang modernize • Firefox - emscripten C++ to asm.js • Chrome - PNaCl C++ LLVM bitcode • Foundation of many OpenCL implementations

Page 27: Modern C++

C++ - pros• Maturity and Performance

• 30 years of evolution and production use in large scale systems • ~ 2x - 3x faster than Java • ~ 10x - 100x faster than Ruby and Python

• Compiler and architecture choices • GCC 4.9, Clang 3.4, Intel C++ 14, Visual C++ 2013, etc

• Easy access to processor features • SSE4 Streaming Extensions, AVX-512 SIMD Vector Extensions

• Compile time static checking and type safety • Static analysis tools, valgrind, clang memory sanitizer,…

• Multi-paradigm • Offers a choice of programming styles

Page 28: Modern C++

C++ - cons• Big language, big learning curve

• Define an idiom with C++: google c++ style • Long compile times

• Idea is to spend time now to save it in the future • Missing standard libraries

• networking, database, graphics, sound, xml and json serialization, etc

• The cost of runtime performance • Buffer overflows,Illegal memory accesses • Requires static analysis • Potential solution: Intel MPX (Memory Protection Extensions)

Page 29: Modern C++

Conclusion

• Pick the right language for the job • C++ is suitable for infrastructure code where

performance and type safety are important • C++ requires care with memory management

(leaks, buffer offer-flows, off-by-one errors) • Give C++ a go!

Page 30: Modern C++

Comments / Questions