herb sutter. what what makes “c++11 feel like a new language” why values and tenets for...
DESCRIPTION
What What makes “C++11 feel like a new language” Why Values and tenets for language design Contrast between native C++ and managed Java/.NET languagesTRANSCRIPT
(Not Your Father’s) C++
Herb Sutter
Roadmap
What What makes “C++11 feel like a new language”
Why Values and tenets for language design Contrast between native C++ and managed Java/.NET languages
“C++11 Feels Like a New Language” Corollary: Lots of what people “know” about C++ is no longer true.
Changes to coding style/idioms/guidance. That’s why it feels new. Style/idioms/guidance define a language.
Features that significantly change style/idioms/guidance include:
Core Language
auto range-for
lambdas move semantics
uniform initialization
Library
smart pointers
async & future
Taste of C++11string flip( string s ) { reverse( begin(s), end(s) ); return s;}
int main() { vector<future<string>> v;
v.push_back( async([]{ return flip(" ,olleH"); }) ); v.push_back( async([]{ return flip( ".gnaL"); }) ); v.push_back( async([]{ return flip("\n!TXEN"); }) );
for( auto& e : v ) { cout << e.get(); }}
Taste of C++11string flip( string s ) { reverse( begin(s), end(s) ); return s;}
int main() { vector<future<string>> v;
v.push_back( async([]{ return flip(" ,olleH"); }) ); v.push_back( async([]{ return flip( ".gnaL"); }) ); v.push_back( async([]{ return flip("\n!TXEN"); }) );
for( auto& e : v ) { cout << e.get(); }}
always there: scoped lifetimes by construction (stack, member)
strongly exception-safe
deterministic
Taste of C++11string flip( string s ) { reverse( begin(s), end(s) ); return s;}
int main() { vector<future<string>> v;
v.push_back( async([]{ return flip(" ,olleH"); }) ); v.push_back( async([]{ return flip( ".gnaL"); }) ); v.push_back( async([]{ return flip("\n!TXEN"); }) );
for( auto& e : v ) { cout << e.get(); }}
Taste of C++11string flip( string s ) { reverse( begin(s), end(s) ); return s;}
int main() { vector<future<string>> v;
v.push_back( async([]{ return flip(" ,olleH"); }) ); v.push_back( async([]{ return flip( ".gnaL"); }) ); v.push_back( async([]{ return flip("\n!TXEN"); }) );
for( auto& e : v ) { cout << e.get(); }}
asynchrony
201x’s best friend
Taste of C++11string flip( string s ) { reverse( begin(s), end(s) ); return s;}
int main() { vector<future<string>> v;
v.push_back( async([]{ return flip(" ,olleH"); }) ); v.push_back( async([]{ return flip( ".gnaL"); }) ); v.push_back( async([]{ return flip("\n!TXEN"); }) );
for( auto& e : v ) { cout << e.get(); }}
lambdas
invasion of the functionals
capture by ref or by value
Taste of C++11string flip( string s ) { reverse( begin(s), end(s) ); return s;}
int main() { vector<future<string>> v;
v.push_back( async([]{ return flip(" ,olleH"); }) ); v.push_back( async([]{ return flip( ".gnaL"); }) ); v.push_back( async([]{ return flip("\n!TXEN"); }) );
for( auto& e : v ) { cout << e.get(); }}
Taste of C++11string flip( string s ) { reverse( begin(s), end(s) ); return s;}
int main() { vector<future<string>> v;
v.push_back( async([]{ return flip(" ,olleH"); }) ); v.push_back( async([]{ return flip( ".gnaL"); }) ); v.push_back( async([]{ return flip("\n!TXEN"); }) );
for( auto& e : v ) { cout << e.get(); }}
// <-- look ma, no *
Taste of C++11string flip( string s ) { reverse( begin(s), end(s) ); return s;}
int main() { vector<future<string>> v;
v.push_back( async([]{ return flip(" ,olleH"); }) ); v.push_back( async([]{ return flip( ".gnaL"); }) ); v.push_back( async([]{ return flip("\n!TXEN"); }) );
for( auto& e : v ) { cout << e.get(); }}
move semantics=
the semantics of value types (no pointers! declared lifetime!)
+ the efficiency of reference types
(no deep copying!)
Taste of C++11string flip( string s ) { reverse( begin(s), end(s) ); return s;}
int main() { vector<future<string>> v;
v.push_back( async([]{ return flip(" ,olleH"); }) ); v.push_back( async([]{ return flip( ".gnaL"); }) ); v.push_back( async([]{ return flip("\n!TXEN"); }) );
for( auto& e : v ) { cout << e.get(); }}
Hello, Lang.NEXT!
Taste of C++11string flip( string s ) { reverse( begin(s), end(s) ); return translate_to_french( move(s) );}
int main() { vector<future<string>> v;
v.push_back( async([]{ return flip(" ,olleH"); }) ); v.push_back( async([]{ return flip( ".gnaL"); }) ); v.push_back( async([]{ return flip("\n!TXEN"); }) );
for( auto& e : v ) { cout << e.get(); }}
Bonjour, Langue.SUIVANTE!
program is guaranteed to allocate only three strings
high compute / low latency
Smart Pointers:Portable Type & Memory Safety
Use unique_ptr by default, and shared_ptr/weak_ptr to express shared ownership/observation. Avoid “new” and “delete.”
Use a non-owning * or & to observe an object that will outlive you.
C++98 C++11widget* pw = new widget();delete pw;
auto pw = make_shared<widget>();
class node { vector<node*> children; node* parent;
class node { vector<unique_ptr<node>> children; node* parent;
DELETE
What’s Different: At a GlanceThen Nowcircle* p = new circle( 42 );
vector<shape*> vw;load_shapes( vw );
for( vector<circle*>::iterator i = vw.begin(); i != vw.end(); ++i ) { if( (*i)->weight() > 100 ) cout << **i << “ is a match\n”;}
for( vector<circle*>::iterator i = vw.begin(); i != vw.end(); ++i ) { delete *i;}
delete p;
auto p = make_shared<circle>( 42 );
auto vw = load_shapes();
for( auto& s : vw ) { if( s->weight() > 100 ) cout << *s << “ is a match\n”;}
T* shared_ptr<T>new make_shared
no need for “delete”automatic lifetime management
exception-safe
range-for
auto type deduction
not exception-safemissing try/catch,
__try/__finally
return by value + move+ auto again to deduce
vector<shared_ptr<shape>>
Clean, Safe, Fast
With C++11, modern C++ code is clean, safe, and fast.
As clean and safe as any other modern language. “When used in a modern style.” – Bjarne Stroustrup
Was always fast. Now even faster. Move semantics, constexpr.
Roadmap
What What makes “C++11 feel like a new language”
Why Values and tenets for language design Contrast between native C++ and managed Java/.NET languages
C++ Values & Tenets Never compromise on performance and control.
Efficient abstraction (e.g., inlining by default) Flexibility to express exactly what you need (e.g., specialization) Exact control over memory layout (e.g., stack/member allocation) Determinism and ordering WYSIWYG (e.g., stack/member lifetime)
Deeply believe in trust and zero overhead. “Leave no room for a language lower than C++” other than asm “Zero overhead” / “Don’t pay for what you don’t use” “Trust the programmer” ( pitfalls! still give usability, guard rails) “Always provide a way to open the hood and get down to the metal”
C++ Values & Tenets Never compromise on performance and control.
Efficient abstraction (e.g., inlining) Flexibility to express exactly what you need (e.g., specialization) Exact control over memory layout (e.g., stack/member allocation) Determinism and ordering WYSIWYG (e.g., stack/member lifetime)
Deeply believe in trust and zero overhead. “Leave no room for a language lower than C++” other than asm “Zero overhead” / “Don’t pay for what you don’t use” “Trust the programmer” ( pitfalls! still give usability, guard rails) “Always provide a way to open the hood and get down to the metal”
GPGPU
Priorities He says:
“Provide default-on guard rails and programmer productivity too, but never at the expense of performance and control.”
She says:“Provide performance and control too, but never at the expense of always-on guard rails and programmer productivity.”
Performance& Control Productivity
Perception
Reality
Performance& Control Productivity
Reality
Performance& Control Productivity
virtualauto / var
lambda functionsrange for / foreachimmutable objects
expr templates / LINQfutures
ref typesvalue types
await *static if *
modules *parallel algorithms *
thread-safe containers *hash control **
& much more
“Native” C++ “Managed” Java/C#
Performance& Control Productivity
virtualauto / var
lambda functionsrange for / foreachimmutable objects
expr templates / LINQfutures
ref typesvalue types
await *static if *
modules *parallel algorithms *
thread-safe containers *hash control **
& much more
always-on / default-ongarbage collection
virtual machinemetadata
default assumptionsvirtual dispatch
dynamic obj layoutnondeterministic
unordered (e.g., fzer)
simplificationslambdas ref-capture alwaysone-shot/type-erased C<T>
(hash automation)
recommended / opt-insmart pointers
garbage collection *
default assumptionsinlinability
predictable obj layoutdeterministic
ordered (e.g., dtor)(big-Oh of operations)
power-upslambda ref|value capture
specializable templates(hash control)
C++11C++11
ISO C++
C++98 C++98
language library
K&R CK&R C
proxies for size comparisons: spec #pages, book #pages
C# 3.0 (2008)Java 7 (2011)C# 4.0 (2010)
1979-1989Research: C
with Classes, ARM C++
1989-1999MainstreamC++ goes to town (& ISO, & space, &c)
1999-2009Coffee-based languages for productivityQ: Can they
do everything important?
2009-Native code invited back
from exile with the Return of
the King:Performance
Per Watt
Phase/Trend Major Constraints 2x Efficient App Runs…(1950-90s) Compute-constrained Processor 2x compute speed
2x users
* http://perspectives.mvdirona.com/2010/09/18/OverallDataCenterCosts.aspx
(1995ish-2007ish) Surplus local compute + low UI innovation (e.g., 2nd party LOB client WIMP apps)
Programmer time n/a
(200x-) Mobile + bigger experiences (e.g., tablet, ‘smartphone’)
Power (battery life)Processor
2x battery life2x compute speed
(2009-) Cloud / datacenter(e.g., Office 365, Shazam, Siri)
Server HW (57%)Power (31%) *
0.56x nodes0.56x power
(2009-) Heterogeneous cores (e.g., Cell, GPGPU)
Power (dark silicon)Processor
0.5x power envelope2x compute speed
(2020ish-) Moore’s End Processor 2x compute speed forever
* http://perspectives.mvdirona.com/2010/09/18/OverallDataCenterCosts.aspx
(200x-) Mobile + bigger experiences (e.g., tablet, ‘smartphone’)
Power (battery life)Processor
2x battery life2x compute speed
(2009-) Cloud / datacenter(e.g., Office 365, Shazam, Siri)
Server HW (57%)Power (31%) *
0.56x nodes0.56x power
(2009-) Heterogeneous cores (e.g., Cell, GPGPU)
Power (dark silicon)Processor
0.5x power envelope2x compute speed
(2020ish-) Moore’s End Processor 2x compute speed forever
Note: The final four are going to dominate for the rest of our careers.
Phase/Trend Major Constraints 2x Efficient App Runs…
When the business model is to charge for CPU hours, you had better make sure that you are giving customers something that is as resource efficient as possible.“
Niklas Gustafsson
“”
Observations: [on Enterprise vs. Cloud ]
• People costs shift from top to nearly irrelevant.
• Work done/$ and work done/W are whatreally matters (S/W issues dominate).
• Expect high-scale service techniques to spread to enterprise.
James HamiltonVP & Distinguished Engineer, Amazon Web Serviceshttp://www.mvdirona.com/jrh/TalksAndPapers/JamesHamilton_USENIX2009.pdfhttp://perspectives.mvdirona.com/2010/09/18/OverallDataCenterCosts.aspxhttp://mvdirona.com/jrh/TalksAndPapers/JamesHamilton_WhereDoesThePowerGo.pdf
“”
C++ Developer Survey (Feb 2012)Q: How long has your current application been in development? (N=387)
What’s Your Biggest Cost? “Find your biggest cost, and optimize that.”
Where programmer time is your biggest cost/constraint, and you can afford some overheads, optimize for programmer productivity – consider suitable languages (there).
Where performance / {$|T|W} and/or layout/resources/determinism control is your biggest cost/constraint, optimize for performance and control – consider modern C++ (there).
Every well designed language is a finely crafted tool optimized for specific priorities and purpose. Use the right tool for the job. It’s a mistake to try to make C#/Java do what C++ does, and vice versa. (Hammer vs. screwdriver; prevention vs. cure; working with vs. against.)
Summary Modern C++ is clean, safe, and fast.
Strong abstraction: Type-safe OO and generic code for modeling power, without sacrificing control and efficiency.
Full control over code and memory: You can always express what you want to do. You can always control memory and data layout exactly.
Pay-as-you-go efficiency: No mandatory overheads.
“The going word at Facebook is that ‘reasonably written C++ code just runs fast,’ which underscores the enormous effort spent at optimizing PHP
and Java code. Paradoxically, C++ code is more difficult to write than in other languages, but efficient code is a lot easier.” – Andrei Alexandrescu