0% found this document useful (0 votes)
65 views60 pages

The Design of C++0x: Bjarne Stroustrup

The document summarizes the key design principles and goals of C++0x, the next version of the C++ programming language. It emphasizes maintaining stability and compatibility, supporting both experts and novices, preferring libraries over language extensions, generality over specialization, increasing type safety, and improving performance while working directly with hardware. The overall goals are to make C++ a better language for systems programming and library building.

Uploaded by

Alberto Balda
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
65 views60 pages

The Design of C++0x: Bjarne Stroustrup

The document summarizes the key design principles and goals of C++0x, the next version of the C++ programming language. It emphasizes maintaining stability and compatibility, supporting both experts and novices, preferring libraries over language extensions, generality over specialization, increasing type safety, and improving performance while working directly with hardware. The overall goals are to make C++ a better language for systems programming and library building.

Uploaded by

Alberto Balda
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 60

The Design of C++0x

Bjarne Stroustrup
Texas A&M University
http://www.research.att.com/~bs

Caveat
There are people who want just the facts, just the technical details
Im writing the C++0x FAQ for you If you really want all the details, read the draft standard (hard) Technical details in isolation are sterile

There are people who want grand theory, fundamental principles, and no distracting details
I dont do that Theory in isolation is sterile

This talk
Gives a bit of background (history) and some simple design principles illustrated by the simplest code examples I can find
Stroustrup - CERN 2009 3

Overview
Aims, Ideals, and history C++ Design rules for C++0x
With examples

Case studies
Initialization Concurrency

Stroustrup - CERN 2009

8000+ Programming Languages


C++s family tree (part of)
Assembler Pascal Fortran Algol
BCPL

Ada
Object Pascal

Ada95 C89/99

C++
Simula ML Lisp Smalltalk Java

C++0x

C#

And this is a gross oversimplification!


Stroustrup - CERN 2009 5

Programming languages
A programming language exists to help people express ideas Programming language features exist to serve design and programming techniques The primary value of a programming language is in the applications written in it

The quest for better languages has been long and continues
Stroustrup - CERN 2009 6

Assembler 1951
Machine code to assembler and libraries
Abstraction Efficiency Testing documentation

Stroustrup - CERN 2009

Fortran 1956
A notation fit for humans
For a specific application domain
A(I) = B(I)+C*D(I)

Efficiency a premium Portability

Stroustrup - CERN 2009

Simula 1967
Organize code to model the real world
Object-oriented design

Let the users define their own types (classes)


In general: concepts/ideas map to classes Data abstraction

Organize classes into hierarchies


Object-oriented programming

Stroustrup - CERN 2009

C 1974
An simple and general notation for systems programming
Somewhat portable Direct mapping of objects and basic operations to machine
Performance becomes somewhat portable

Stroustrup - CERN 2009

10

C with Classes 1980


General abstraction mechanisms to cope with complexity
From Simula

General close-to-hardware machine model for efficiency


From C Became C++ in 1984 Commercial release 1985 ISO standard 1998 2nd ISO standard 200x (x is hex )

Stroustrup - CERN 2009

11

ISO Standard C++


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
From mid-1983 From about 1990

From day 1 (1980)

The most effective styles use a combination of techniques


Focus of C++0x work
Stroustrup - CERN 2009 12

Whats distinctive about C++?


Stability
Essential for real-world software 1985-2008 1978-2008 (C and C with Classes)

Non-proprietary
Yet almost universally supported ISO standard from 1998

Direct interface to other languages


Notably C, assembler, Fortran

Abstraction + machine model


Zero overhead principle
For basic operations and abstraction mechanisms

User-defined types receive the same support as built-in types Standard library written in the language itself
And most non-standard libraries
Stroustrup - CERN 2009 13

C++ is everywhere
http://www.research.att.com/~bs/applications.html
Telecommunications Google Microsoft applications and GUIs Linux tools and GUIs Games PhotoShop Finance Mars Rovers Marine diesel engines Cell phones Human genome project Micro electronics design and manufacturing
14

Stroustrup - CERN 2009

C++ ISO Standardization


Slow, bureaucratic, democratic, formal process About 22 nations (5 to 12 at a meeting) Membership have varied
100 to 200+
200+ members currently

40 to 100 at a meeting
~60 currently

Most members work in industry Most members are volunteers


Even many of the company representatives

Most major platform, compiler, and library vendors are represented


E.g., IBM, Intel, Microsoft, Sun

End users are underrepresented


Stroustrup - CERN 2009 15

Design?
Can a committee design?
No (at least not much) Few people consider or care for the whole language

Is C++0x designed
Yes
Well, mostly You can see traces of different personalities in C++0x

Committees
Discuss Bring up problems Polish

Stroustrup - CERN 2009

17

Template meta-programming!

What is C++?
A hybrid language A multi-paradigm programming language Its C! Embedded systems programming language Supports generic programming A random collection 19 of features

Buffer overflows

Too big!

Low level! An object-oriented programming language

Stroustrup - CERN 2009

C++0x
It feels like a new language
Compared to C++98

How can I categorize/characterize it? Its not just object oriented


Many of the key user-defined abstractions are not objects
Types Classifications and manipulation of types (types of types)
I miss concepts

Algorithms (generalized versions of computation) Resources and resource lifetimes

The pieces (language features) fit together much better than they used to Stroustrup - CERN 2009 20

A language for building software infrastructures and resourceconstrained applications

C++

A light-weight abstraction programming language


Stroustrup - CERN 2009 21

So, what does light-weight abstraction mean?


The design of programs focused on the design, implementation, and use of abstractions
Often abstractions are organized into libraries
So this style of development has been called library-oriented

C++ emphasis
Flexible static type system Performance (in time and space) Small abstractions

Stroustrup - CERN 2009

22

Overall goals for C++0x


Make C++ a better language for systems programming and library building
Rather than providing specialized facilities for a particular subcommunity (e.g. numeric computation or Windows-style application development) Build directly on C++s contributions to systems programming

Make C++ easier to teach and learn


Through increased uniformity, stronger guarantees, and facilities supportive of novices (there will always be more novices than experts)
Stroustrup - CERN 2009 23

Rules of thumb / Ideals


Integrating features to work in combination is the key
And the most work The whole is much more than the simple sum of its part Maintain stability and compatibility Prefer libraries to language extensions Prefer generality to specialization Support both experts and novices Increase type safety Improve performance and ability to work directly with hardware Make only changes that change the way people think Fit into the real world

Stroustrup - CERN 2009

24

Maintain stability and compatibility


Dont break my code!
There are billions of lines of code out there There are millions of C++ programmers out there

Absolutely no incompatibilities leads to ugliness


We introduce new keywords as needed: concept, auto (recycled), decltype, constexpr, thread_local, nullptr, axiom Example of incompatibility: static_assert(4<=sizeof(int),"error: small ints");

Absolutely no incompatibilities leads to absurdities


_Bool // C99 boolean type typedef _Bool bool; // C99 standard library typedef
Stroustrup - CERN 2009 25

Support both experts and novices


Example: minor syntax cleanup
vector<list<int>> vl; // note the missing space

Example: simplified iteration


for (auto x : v) cout << x <<'\n';

Note: Experts dont easily appreciate the needs of novices


Example of what we couldnt get just now string s = "12.3"; double x = lexical_cast<double>(s);

// extract value from string

Stroustrup - CERN 2009

26

Prefer libraries to language extensions


Libraries deliver more functionality Libraries are immediately useful Problem: Enthusiasts prefer language features
see library as 2 nd best

Example: New library components


std::thread, std::unique_future,
Threads ABI; not thread built-in type

std::unordered_map, std::regex,
Not built-in associative array

Example: Mixed language/library extension


The new for works for every type with std::begin() and std::end() The new initializer lists are based on std::initializer_list<T> vector<string> v = { "Nygaard ", "Ritchie" }; for (auto& x : {y,z,ae,ao,aa}) cout << x <<'\n';
Stroustrup - CERN 2009 27

Prefer generality to specialization


Example: Prefer improvements to abstraction mechanisms over separate new features
Inherited constructor
template<class T> class Vector : std::vector<T> { using vector::vector<T>; // inherit all constructors // };

Move semantics supported by rvalue references


template<class T> class vector { // void push_back(const T&& x); }; // move x into vector // avoid copy if possible

Problem: people love small isolated features


Stroustrup - CERN 2009 28

Increase type safety


Approximate the unachievable ideal
Example: Strongly-typed enumerations
enum class Color { red, blue, green }; int x = Color::red; // error: no Color->int conversion Color y = 7; // error: no int->Color conversion Color z = red; // error: red not in scope Color c = Color::red; // fine

Example: Support for general resource management


std::unique_ptr (for ownership) std::shared_ptr (for sharing) Garbage collection ABI

Stroustrup - CERN 2009

29

Improve performance and the ability to work directly with hardware


Embedded systems programming is very important
Example: address array/pointer problems
array<int,7> s; // fixed-sized array

Example: Generalized constant expressions (think ROM)


constexpr int abs(int i) { return (0<=i) ? i : -i; } struct Point { int x, y; constexpr Point(int xx, int yy) : x(xx), y(yy) { } }; constexpr Point p1(1,2); // ok constexpr Point p2(1,abs(x)); // error unless x is a constant expression
Stroustrup - CERN 2009 30

Make only changes that change the way people think


Think/remember:
Object-oriented programming Generic programming Concurrency

But, most people prefer to fiddle with details


So there are dozens of small improvements
All useful somewhere long long, static_assert, raw literals, thread_local, unicode types,

Example: A null pointer keyword


void f(int); void f(char*); f(0); f(nullptr); // call f(int); // call f(char*);
Stroustrup - CERN 2009 31

Fit into the real world


Example: Existing compilers and tools must evolve
Simple complete replacement is impossible Tool chains are huge and expensive There are more tools than you can imagine C++ exists on many platforms
So the tool chain problems occur N times
(for each of M tools)

Example: Education
Teachers, courses, and textbooks
Often mired in 1970s thinking (C is the perfect language) or 1980s thinking (OOP Rah Rah Rah)

We havent completely caught up with C++98!


legacy code breeds more legacy code
Stroustrup - CERN 2009 32

Areas of language change


Machine model and concurrency Model
Threads library (std::thread) Atomic ABI Thread-local storage (thread_local) Asynchronous message buffer (std::future)

Support for generic programming


(concepts ) uniform initialization auto, decltype, lambdas, template aliases, move semantics, variadic templates, range-for,

Etc.
static_assert improved enums long long, C99 character types, etc. Stroustrup - CERN 2009

33

Case studies
Concurrency
driven by necessity

Initialization
language maintenance

Stroustrup - CERN 2009

34

Case study: Concurrency


What we want
Ease of programming
Writing correct concurrent code is hard

Portability Uncompromising performance System level interoperability

We cant get everything


No one concurrency model is best for everything De facto: we cant get all that much C++ is a systems programming language
(among other things) implies serious constraints

Stroustrup - CERN 2009

35

Concurrency
Not
Massively parallel (scientific) computing Web services Simple high-level abstract model System of real-time guarantees

Instead
A systems-level foundation for all
Stroustrup - CERN 2009 36

Concurrency overview
Foundation
Memory model atomics

Concurrency library components


std::thread std::mutex (several) std::lock (several) std::condition (several) std::future, std::promise, std::packaged_task std::async()

Resource management
std::unique_ptr, std::shared_ptr Stroustrup - CERN 2009 GC ABI
37

Memory model
A memory model is an agreement between the machine architects and the compiler writers to ensure that most programmers do not have to think about the details of modern computer hardware.
// thread 1: char c; c = 1; int x = c; // thread 2: char b; b = 1; int y = b;

x==1 and y==0 as anyone would expect (but dont try that for two bitfields of the same word)

Stroustrup - CERN 2009

38

Atomics (here be dragons!)


Components for fine-grained atomic access
provided via operations on atomic objects (in <cstdatomic>) Low-level, messy, and shared with C (making the notation messy) what you need for lock-free programming what you need to implement std::thread, std::mutex, etc. Several synchronization models, CAS, fences,

enum memory_order { // regular (non-atomic) memory synchronization order memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst }; C atomic_load_explicit(const volatile A* object, memory_order); void atomic_store_explicit(volatile A *object, C desired, memory_order order); bool atomic_compare_exchange_weak_explicit(volatile A* object, C * expected, C desired, memory_order success, memory_order failure); Stroustrup - CERN 2009 39 // lots more

Concurrency: std::thread
#include<thread> void f() { std::cout << "Hello "; struct F { void operator()() { std::cout << "parallel world "; } }; int main() { std::thread t1{f}; // f() executes in separate thread std::thread t2{F()}; // F()() executes in separate thread } // spot the bugs

Stroustrup - CERN 2009

40

Concurrency: std::thread
int main() { std::thread t1{f}; std::thread t2{F()}; t1.join(); t2.join(); } // and another bug: dont write to cout without synchronization // f() executes in separate thread // F()() executes in separate thread

// wait for t1 // wait for t2

Stroustrup - CERN 2009

41

Mutual exclusion: std::mutex


A mutex is a primitive object use for controlling access in a multi-threaded system. A mutex is a shared object (a resource) Simplest use:
std::mutex m; int sh; // shared data // ... m.lock(); // manipulate shared data: sh+=1; m.unlock();
Stroustrup - CERN 2009 42

Mutual exclusion: std::mutex


Not all mutex uses are simple:
std::timed_mutex m; int sh; // shared data // ... if (m.try_lock_for(std::chrono::seconds(10))) { // manipulate shared data: sh+=1; m.unlock(); } else { // we didn't get the mutex; do something else }
Stroustrup - CERN 2009

// Note: time

43

RAII for mutexes: std::lock


A lock represents local ownership of a non-local resource (the mutex)
std::mutex m; int sh; // shared data void f() { // ... std::unique_lock lck(m); // grab (acquire) the mutex // manipulate shared data: sh+=1; } // implicitly release the mutex
Stroustrup - CERN 2009 44

RAII for mutexes: std::lock


We can safely use several locks
void f() { // ... std::unique_lock lck1(m1,std::defer_lock); // make locks but don't yet // try to acquire the mutexes std::unique_lock lck2(m2,std::defer_lock); std::unique_lock lck3(m3,std::defer_lock); lock(lck1,lck2,lck3); // manipulate shared data }

Stroustrup - CERN 2009

45

Future and promise


get() future promise set()

result

future+promise provides a simple way of passing a value from one thread to another
No explicit synchronization Exceptions can be transmitted between threads
Stroustrup - CERN 2009 46

Future and promise


Get from a future:
X v = f.get();// if necessary wait for the value to get

Put to a promise:
try { X res; // compute a value for res p.set_value(res); } catch (...) { // oops: couldn't compute res p.set_exception(std::current_exception()); }
Stroustrup - CERN 2009 47

async()
Simple launcher (warning: only approved in principle)
template<class T, class V> struct Accum { // accumulator function object }; void comp(vector<double>& v) // spawn many tasks if v is large enough { if (v.size()<10000) return std::accumulate(v.begin(),v.end(),0.0); auto f0 = async(Accum{&v[0],&v[v.size()/4],0.0}); auto f1 = async(Accum{&v[v.size()/4],&v[v.size()/2],0.0}); auto f2 = async(Accum{&v[v.size()/2],&v[v.size()*3/4],0.0}); auto f3 = async(Accum{&v[v.size()*3/4],&v[v.size()],0.0}); return f0.get()+f1.get()+f2.get()+f3.get(); } Stroustrup - CERN 2009 48

Future
Lots of use
C++98, C++0x, C++1x,

Is there a future for the C++ model beyond C++?


Direct map to hardware Zero-overhead abstraction Minimal run-time environment Destructor-based resource management Heavy use of stack

yes

Challenges
Small language (or at least much, much smaller) Complete and enforced type safety Concurrency
Stroustrup - CERN 2009

I think it can be done

49

Thanks!
C and Simula
Brian Kernighan Doug McIlroy Kristen Nygaard Dennis Ritchie Steve Clamage Francis Glassborow Andrew Koenig Tom Plum Herb Sutter

ISO C++ standards committee


C++ compiler, tools, and library builders


Beman Dawes David Vandevoorde

Application builders
Stroustrup - CERN 2009 50

More information
My HOPL-II and HOPL-III papers The Design and Evolution of C++ (Addison Wesley 1994) My home pages
Papers, FAQs, libraries, applications, compilers,
Search for Bjarne or Stroustrup

C++0x FAQ

The ISO C++ standard committees site:


All documents from 1994 onwards
Search for WG21

The Computer History Museum


Software preservation projects C++ pages
Early compilers and documentation, etc. http://www.softwarepreservation.org/projects/c_plus_plus/ Search for C++ Historical Sources Archive
Stroustrup - CERN 2009 51

C++0x examples
// bind a template argument (Currying): template<class T> using Vec = std::vector<T,My_alloc<T>>; // an alias Vec<double> v = { 1, 2.2, 3, 9 }; // Note: general and uniform initialization sort(v); // simplicity is the ultimate sophistication (and no spurious overheads) sort({"Nygaard", "Ritchie", "Richards"}); // error: can sort a constant for (auto x : v ) cout << x <<'\n'; // simple traversal // run in parallel: auto x = asynch([&v]() { return accumulate(v.begin(), v.end(), 0.0); }); // a lambda // double d = x.get(); // if necessary, wait for result
Stroustrup - CERN 2009 52

C++0x examples
struct F { // function object F(const string&); double operator()(double, int); // application (function call) operator // }; auto f = bind(F("Hello"), _1, 42); // _1 is a placeholder double dd = f(1.23); // F(hello)(1.23,42);

Stroustrup - CERN 2009

53

Problem #1: irregularity


There are four notations and none can be used everywhere
int a = 2; int[] aa = { 2, 3 }; complex z(1,2); x = Ptr(y); // assignment style // assignment style with list // functional style initialization // functional style for conversion/cast/construction

Sometimes, the syntax is inconsistent/confusing


int a(1); int b(); int b(foo); // variable definition // function declaration // variable definition or function declaration

We cant use initializer lists except in a few cases


string a[] = { "foo", " bar" }; // ok: initialize array variable vector<string> v = { "foo", " bar" }; // error: initialize vector variable void f(string a[]); 55 f( { "foo", " bar" } ); // error: initializer array argument

Is irregularity a real problem?


Yes, a major source of confusion and bugs Can it be solved by restriction?
No existing syntax can be used in all cases
int a [] = { 1,2,3 }; complex<double> z(1,2); struct S { double x,y; } s = {1,2}; int* p = new int(4); typedef char* Pchar; Pchar p(7); Pchar p = Pchar(7); // cant use () here // cant use { } here // cant use ( ) here // cant use { } or = here

No existing syntax has the same semantics in all cases


// error (good!) // legal (ouch!)

Principle violated:
Uniform support for types (user-defined and built-in)
56

Problem #2: list workarounds


Initialize a vector
(using push_back)

Clumsy and indirect


template<class T> class vector { // void push_back(const T&) { /* */ } // }; vector<double> v; v.push_back(1.2); v.push_back(2.3); v.push_back(3.4);

Principle violated:
Support fundamental notions directly (state intent)
57

Problem #2: list workarounds


Initialize vector
(using general iterator constructor)

Awkward, error-prone, and indirect Spurious use of (unsafe) array


template<class T> class vector { // template <class Iter> vector(Iter first, Iter last) { /* */ } // }; int a[ ] = { 1.2, 2.3, 3.4 }; vector<double> v(a, a+sizeof(a)/sizeof(int)); // bug // hazard

Principle violated:
Support user-defined and built-in types equally well
58

C++0x: initializer lists


An initializer-list constructor
defines the meaning of an initializer list for a type
template<class T> class vector { // vector(std::initializer_list<T>); // }; vector<double> v = { 1, 2, 3.4 }; vector<string> geek_heros = { "Dahl", "Kernighan", "McIlroy", "Nygaard ", "Ritchie", "Stepanov" 59 };

// initializer list constructor

C++0x: initializer lists


Not just for templates and constructors
but std::initializer list is simple does just one thing well

void f(int, std::initializer_list<int>, int); f(1, {2,3,4}, 5); f(42, {1,a,3,b,c,d,x+y,0,g(x+a),0,0,3}, 1066);

60

Uniform initialization syntax


Every form of initialization can accept the { } syntax
X x1 = X{1,2}; X x2 = {1,2}; // the = is optional X x3{1,2}; X* p2 = new X{1,2}; struct D : X { D(int x, int y) :X{x,y} { /* */ }; }; struct S { int a[3]; S(int x, int y, int z) :a{x,y,z} { /* */ }; // solution to old problem }; 61

Uniform initialization semantics


X { a } constructs the same value in every context
{ } initialization gives the same result in all places where it is legal X x{a}; X* p = new X{a}; z = X{a}; // use as cast f({a}); // function argument (of type X) return {a}; // function return value (function returning X)

X { } is always an initialization
X var{} // no operand; default initialization
Not a function definition like X var();

X var{a} // one operand


Never a function definition like X var(a); (if a is a type name)
62

Initialization problem #3: narrowing


C++98 implicitly truncates
int x = 7.3; char c = 2001; int a[] = { 1,2,3.4,5,6 }; void f1(int); void f2(char); void f3(int[]); // Ouch! // Ouch! // Ouch! // Ouch! // Ouch! // oh! Another problem

f1(7.3); f2(2001); f3({ 1,2,3.4,5,6 });

A leftover from before C had casts! Principle violated:


Type safety

Solution:
C++0x { } initialization doesnt narrow.
all examples above are caught
63

Uniform Initialization
Example
Table phone_numbers = { { "Donald Duck", 2015551234 }, { Mike Doonesbury", 9794566089 }, { "Kell Dewclaw", 1123581321 } };

What is Table?
a map? An array of structs? A vector of pairs? My own class with a constructor? A struct needing aggregate initialization? Something else? We dont care as long as it can be constructed using a C-style string and an integer. Those numbers cannot get truncated
64

You might also like