SlideShare ist ein Scribd-Unternehmen logo
1 von 89
Downloaden Sie, um offline zu lesen
C++ ‒ a Monster
that no one likes
but that will outlast them all
Yauheni Akhotnikau
2
Started programming somewhere in 1990.
The first meet with C++ in 1991.
C++ is the main tool since 1992 with a few short pauses.
Used some other languages. For example: Pascal, Visual Basic, Java, Ruby, D,
Eiffel, Scala.
I can use C++ without a pain but I don't think that C++ is the greatest
language ever.
A few words about me
3
A bit of C++ evolution history.
Why C++ became popular and why C++ started to lose its popularity.
Why C++ is a Monster? If C ++ is a monster, then why does someone need
C++?
How to use C++ safely and efficiently?
Where and when C++ can be used. If it can...
Pressure to C++ from competitors. Real and imaginary.
Agenda
4
The history and evolution of C++
(and some taste of C++)
5
By the help of a simple demo application:
• there is a collection of struct place (each struct contains name, price and rating);
• sort this collection by rating, then by price, then by name. And then print the collection after
sorting;
• sort this collection by name, then print it.
A way to see the evolution in examples
6
Work on C++ began in 1979.
Bjarne Stroustrup decided to build a language with power of Simula 67 and
efficiency of C.
The first name of the new language was "C with Classes". Name C++
appeared in 1983.
The first public release in 1985.
The birth of C++
7
struct place {
char * name_;
long price_;
int rating_;
place() : name_(0) {}
place(const char * name, long price, int rating)
: name_(copy_name(name)), price_(price), rating_(rating) {}
place(const place & o)
: name_(copy_name(o.name_)), price_(o.price_), rating_(o.rating_) {}
~place() { delete[] name_; }
place & operator=(const place & o) {
char * copy = copy_name(o.name_);
delete[] name_;
name_ = copy; price_ = o.price_; rating_ = o.rating_;
return *this;
}
static char * copy_name(const char * src) {
char * r = 0;
if(src) {
r = new char[strlen(src) + 1];
strcpy(r, src);
}
return r;
}
};
A taste of ancient C++ (pre-C++98)
8
ostream & operator<<(ostream & to, const place & p) {
to << setw(20) << left << p.name_ << "[" << p.rating_ << "]"
<< setw(7) << right << p.price_;
return to;
}
void print(const place * places, size_t count) {
for(size_t i = 0; i != count; ++i)
cout << places[i] << endl;
cout << endl;
}
A taste of ancient C++ (pre-C++98)
9
int compare_by_rating_price_name(const void * av, const void * bv) {
const place & a = *(const place *)av;
const place & b = *(const place *)bv;
int result;
if(a.rating_ < b.rating_) result = -1;
else {
if(a.rating_ == b.rating_) {
if(a.price_ < b.price_) result = -1;
else {
if(a.price_ == b.price_) {
result = strcmp(a.name_, b.name_);
}
else result = 1;
}
}
else result = 1;
}
return result;
}
int compare_by_name(const void * av, const void * bv) {
const place & a = *(const place *)av;
const place & b = *(const place *)bv;
return strcmp(a.name_, b.name_);
}
A taste of ancient C++ (pre-C++98)
10
void get_places(place *& places, size_t & count) {
places = new place[7];
places[0] = place("Moscow", 1500, 3);
places[1] = place("St. Petersburg", 1300, 5);
places[2] = place("Minsk", 500, 4);
places[3] = place("Tokyo", 3500, 4);
places[4] = place("Sydney", 5000, 3);
places[5] = place("Paris", 3000, 5);
places[6] = place("London", 3500, 4);
count = 7;
}
A taste of ancient C++ (pre-C++98)
11
int main() {
place * places;
size_t count;
get_places(places, count);
qsort(places, count, sizeof(place), compare_by_rating_price_name);
print(places, count);
qsort(places, count, sizeof(place), compare_by_name);
print(places, count);
delete[] places;
}
A taste of ancient C++ (pre-C++98)
12
Moscow [3] 1500
Sydney [3] 5000
Minsk [4] 500
London [4] 3500
Tokyo [4] 3500
St. Petersburg [5] 1300
Paris [5] 3000
London [4] 3500
Minsk [4] 500
Moscow [3] 1500
Paris [5] 3000
St. Petersburg [5] 1300
Sydney [3] 5000
Tokyo [4] 3500
A taste of ancient C++ (pre-C++98)
13
1985-1995: fast evolution:
– multiple inheritance, const-methods, protected keyword, namespaces, templates, exceptions,
RTTI, explicit keyword, ...
1990: ANSI/ISO standardization started.
1992: Alex Stepanov started STL.
1994-1998: process of inclusion of STL into the standard.
1998: the first international standard ‒ C++98.
2003: an updated standard ‒ C++03.
1985-2003: main milestones
14
using namespace std;
struct place {
string name_;
long price_;
int rating_;
place() {}
place(const char * name, float price, int rating)
: name_(name), price_(price), rating_(rating) {}
};
A taste of old C++ (C++98)
15
ostream & operator<<(ostream & to, const place & p) {
to << setw(20) << left << p.name_ << "[" << p.rating_ << "]"
<< setw(7) << right << p.price_;
return to;
}
template<class C>
void print(const C & places) {
for(typename C::const_iterator i = places.begin(); i != places.end(); ++i)
cout << *i << endl;
cout << endl;
}
A taste of old C++ (C++98)
16
bool compare_by_rating_price_name(const place & a, const place & b) {
bool result = false;
if(a.rating_ < b.rating_) result = true;
else if(a.rating_ == b.rating_) {
if(a.price_ < b.price_) result = true;
else if(a.price_ == b.price_) result = (a.name_ < b.name_);
}
return result;
}
bool compare_by_name(const place & a, const place & b) {
return a.name_ < b.name_;
}
A taste of old C++ (C++98)
17
vector<place> get_places() {
vector<place> places;
places.push_back(place("Moscow", 1500, 3));
places.push_back(place("St. Petersburg", 1300, 5));
places.push_back(place("Minsk", 500, 4));
places.push_back(place("Tokyo", 3500, 4));
places.push_back(place("Sydney", 5000, 3));
places.push_back(place("Paris", 3000, 5));
places.push_back(place("London", 3500, 4));
return places;
}
A taste of old C++ (C++98)
18
int main() {
vector<place> places = get_places();
sort(places.begin(), places.end(), compare_by_rating_price_name);
print(places);
sort(places.begin(), places.end(), compare_by_name);
print(places);
}
A taste of old C++ (C++98)
19
2003-2011: long-term construction under the name of C++0x.
2011: C++11 released. It's a very different beast!
many, many language improvements;
significant extension of stdlib;
2014: C++14 released. A minor update with some very useful features.
2017: draft of C++17. An important update with lot of new features and
additions to stdlib.
2017: work on C++20 started.
2003-2017: main milestones
20
#include <fmt/format.h>
#include <fmt/ostream.h>
using namespace std;
struct place {
string name_;
long price_;
int rating_;
};
A taste of modern C++ (C++17)
21
ostream & operator<<(ostream & to, const place & p) {
fmt::print(to, "{:<20}[{}]{:7}", p.name_, p.rating_, p.price_);
return to;
}
void print(auto & places) {
for(const auto & p : places)
cout << p << endl;
cout << endl;
}
A taste of modern C++ (C++17)
22
bool compare_by_rating_price_name(const place & a, const place & b) {
return tie(a.rating_, a.price_, a.name_) < tie(b.rating_, b.price_, b.name_);
}
bool compare_by_name(const place & a, const place & b) {
return a.name_ < b.name_;
}
A taste of modern C++ (C++17)
23
vector<place> get_places() {
return {
{"Moscow", 1500, 3},
{"St. Petersburg", 1300, 5},
{"Minsk", 500, 4},
{"Tokyo", 3500, 4},
{"Sydney", 5000, 3},
{"Paris", 3000, 5},
{"London", 3500, 4}
};
}
A taste of modern C++ (C++17)
24
int main() {
auto places = get_places();
sort(begin(places), end(places), compare_by_rating_price_name);
print(places);
sort(begin(places), end(places), compare_by_name);
print(places);
}
A taste of modern C++ (C++17)
25
A shot look to the full demo source code…
1985-2017: the comparison
26
#include <iostream.h>
#include <iomanip.h>
#include <string.h>
#include <stdlib.h>
struct place {
char * name_;
long price_;
int rating_;
place() : name_(0) {}
place(const char * name, long price, int rating)
: name_(copy_name(name)), price_(price), rating_(rating)
{}
place(const place & o)
: name_(copy_name(o.name_)), price_(o.price_),
rating_(o.rating_) {}
~place() {
delete[] name_;
}
place & operator=(const place & o) {
char * copy = copy_name(o.name_);
delete[] name_;
name_ = copy;
price_ = o.price_;
rating_ = o.rating_;
return *this;
}
static char * copy_name(const char * src) {
char * r = 0;
if(src) {
r = new char[strlen(src) + 1];
strcpy(r, src);
}
return r;
}
};
ostream & operator<<(ostream & to, const place & p) {
to << setw(20) << left << p.name_ << "[" << p.rating_ <<
"]"
<< setw(7) << right << p.price_;
return to;
}
void print(const place * places, size_t count) {
for(size_t i = 0; i != count; ++i)
cout << places[i] << endl;
cout << endl;
}
int compare_by_rating_price_name(const void * av, const
void * bv) {
const place & a = *(const place *)av;
const place & b = *(const place *)bv;
int result;
if(a.rating_ < b.rating_) result = -1;
else {
if(a.rating_ == b.rating_) {
if(a.price_ < b.price_) result = -1;
else {
if(a.price_ == b.price_) {
result = strcmp(a.name_, b.name_);
}
else result = 1;
}
}
else result = 1;
}
return result;
}
int compare_by_name(const void * av, const void * bv) {
const place & a = *(const place *)av;
const place & b = *(const place *)bv;
return strcmp(a.name_, b.name_);
}
void get_places(place *& places, size_t & count) {
places = new place[7];
places[0] = place("Moscow", 1500, 3);
places[1] = place("St. Petersburg", 1300, 5);
places[2] = place("Minsk", 500, 4);
places[3] = place("Tokyo", 3500, 4);
places[4] = place("Sydney", 5000, 3);
places[5] = place("Paris", 3000, 5);
places[6] = place("London", 3500, 4);
count = 7;
}
int main() {
place * places;
size_t count;
get_places(places, count);
qsort(places, count, sizeof(place),
compare_by_rating_price_name);
print(places, count);
qsort(places, count, sizeof(place), compare_by_name);
print(places, count);
delete[] places;
}
A taste of… Full text of pre-C++98 demo
27
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;
struct place {
string name_;
long price_;
int rating_;
place() {}
place(const char * name, float price, int rating)
: name_(name), price_(price), rating_(rating) {}
};
ostream & operator<<(ostream & to, const place & p) {
to << setw(20) << left << p.name_ << "[" << p.rating_ << "]"
<< setw(7) << right << p.price_;
return to;
}
template<class C>
void print(const C & places) {
for(typename C::const_iterator i = places.begin(); i != places.end(); ++i)
cout << *i << endl;
cout << endl;
}
bool compare_by_rating_price_name(const place & a, const place & b) {
bool result = false;
if(a.rating_ < b.rating_) result = true;
else if(a.rating_ == b.rating_) {
if(a.price_ < b.price_) result = true;
else if(a.price_ == b.price_) result = (a.name_ < b.name_);
}
return result;
}
bool compare_by_name(const place & a, const place & b) {
return a.name_ < b.name_;
}
vector<place> get_places() {
vector<place> places;
places.push_back(place("Moscow", 1500, 3));
places.push_back(place("St. Petersburg", 1300, 5));
places.push_back(place("Minsk", 500, 4));
places.push_back(place("Tokyo", 3500, 4));
places.push_back(place("Sydney", 5000, 3));
places.push_back(place("Paris", 3000, 5));
places.push_back(place("London", 3500, 4));
return places;
}
int main() {
vector<place> places = get_places();
sort(places.begin(), places.end(), compare_by_rating_price_name);
print(places);
sort(places.begin(), places.end(), compare_by_name);
print(places);
}
A taste of… Full text of C++98 demo
28
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <tuple>
#include <fmt/format.h>
#include <fmt/ostream.h>
using namespace std;
struct place {
string name_;
long price_;
int rating_;
};
ostream & operator<<(ostream & to, const place & p) {
fmt::print(to, "{:<20}[{}]{:7}", p.name_, p.rating_, p.price_);
return to;
}
void print(auto & places) {
for(const auto & p : places)
cout << p << endl;
cout << endl;
}
bool compare_by_rating_price_name(const place & a, const place & b) {
return tie(a.rating_, a.price_, a.name_) < tie(b.rating_, b.price_, b.name_);
}
bool compare_by_name(const place & a, const place & b) {
return a.name_ < b.name_;
}
vector<place> get_places() {
return {
{"Moscow", 1500, 3},
{"St. Petersburg", 1300, 5},
{"Minsk", 500, 4},
{"Tokyo", 3500, 4},
{"Sydney", 5000, 3},
{"Paris", 3000, 5},
{"London", 3500, 4}
};
}
int main() {
auto places = get_places();
sort(begin(places), end(places), compare_by_rating_price_name);
print(places);
sort(begin(places), end(places), compare_by_name);
print(places);
}
A taste of… Full text of C++17 demo
29
Why C++ became
popular?
Why C++ lost its
popularity?
30
A very weak computers. Fight for efficiency is the fight for a life.
Personal Computer was not a toy anymore. It was a new market.
But PCs were yet more weak: "640K ought to be enough for anybody"
OOP was regarded as a "silver bullet" for a software development crisis.
There was a necessity of a complex tool for solving complex problems.
Because almost every problem was a complex one.
C++ was a such tool.
Where was IT-industry at mid of 1980s?
31
Almost everywhere:
– system software;
– middleware;
– server-side;
– desktop (especially on Windows with OLE/COM/DCOM);
– embedded;
– high-performance computing;
– ...
With obvious exceptions in areas where tools like dBase, FoxBase, Clarion,
VisualBasic were in active use.
Where C++ was used before 2000s?
32
Computers become much more powerful.
– Java is not slow now (or it is believed that Java is not slow);
– Microsoft created .NET and C#. Development for Windows is now .NET-centric;
– many application are developed in Python, Ruby, Erlang and so on.
Internet and WWW are not toys anymore. They are a new market.
– Web-development is a new niche;
– migration from desktop to Web has started...
IT-landscape changed at the end of 90s
33
Started at the beginning of 2000s.
Many developers switched to more safe and powerful languages and
platforms like JVM (Java, Scala), .NET (C#, F#), Python, Ruby, Erlang and so
on...
New projects didn't use C++.
Migration of some old projects to other languages started.
Visual Studio as an example.
New big platforms: Apple iOS (Objective-C) and Google's Android (Java).
Hype around Erlang, OCaml, Haskell and similar languages.
The oblivion of C++
34
Why C++ is a Monster?
35
There are objective and subjective reasons.
It is hard to speak about subjective reasons seriously:
– too many features, a developer must think (think?!!!);
– it is not Java nor C# nor SmallTalk nor ...
– the OOP is C++ is totally wrong (so speak Alan Key);
– no Garbage Collector.
But there are some objective reasons which make life of a programmer
harder...
C++ became a monster long time ago
36
C++98 is almost 800 pages.
C++11 is about 1400 pages.
C++17 is about 1700 pages.
Must read books for a C++ developer (only some of them):
"The C++ Programming Language" (Bjarne Stroustrup), "C++ Standard Library Tutorial and
Reference" (Nicolai Josuttis), "C++ Templates: The Complete Guide" (David Vandevoorde and
Nicolai M. Josuttis), "C++ Coding Standards" (Herb Sutter and Andrei Alexandrescu), "Effective
Modern C++" (Scott Meyers) and the previous books from the same author: "Effective C++",
"Effective STL", "More Effective C++".
See more here: The Definitive C++ Book Guide and List.
C++ is a complex language
37
Classical example:
int values[4];
values[4] = 0;
It is easy to shoot to a leg
38
There are many ways to corrupt memory of a program:
– dereference of an invalid pointer;
– out of bound writes;
– violation of type rules (an attempt to cast int* to double*);
– use of uninitialized value;
– double free of memory;
– ...
A program with corrupted memory may crash. Or it may not crash (it much
worse).
Even if it crashes there is no beautiful stack trace or something similar.
A program may crash or may not...
39
There are plenty of UB in the language:
– signed overflow;
– access out of bounds;
– uninitialized scalar;
– null pointer dereference;
– access to pointer passed to realloc;
– infinite loop without side-effects;
– oversized shift;
– violation of type rules;
– modification of the same scalar more than once in an expression;
– ...
Undefined behavior
40
#include <cstdlib>
typedef int (*Function)();
static Function Do;
static int EraseAll() {
return system("rm -rf /");
}
void NeverCalled() {
Do = EraseAll;
}
int main() {
return Do();
}
Undefined behavior (`rm -rf /`)
41
#include <cstdlib>
typedef int (*Function)();
static Function Do;
static int EraseAll() {
return system("rm -rf /");
}
void NeverCalled() {
Do = EraseAll;
}
int main() {
return Do();
}
Undefined behavior (`rm -rf /`)
42
NeverCalled(): # @NeverCalled()
retq
main: # @main
movl $.L.str, %edi
jmp system # TAILCALL
.L.str:
.asciz "rm -rf /"
clang-5.0.0 -Os -std=C++11
https://godbolt.org/g/o4HxtU
Undefined behavior (`rm -rf /`)
43
sort(begin(places), end(places), [](const auto & a, const auto & b) {
const auto t = [](const auto & p) { return tie(p.rating_, p.price_, p.name_); };
return t(a) < tie(b);
});
Hard to read error messages
44
Hard to read error messages
In file included from t1_cpp14_2.cpp:5:0:
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/tuple: In instantiation of 'constexpr bool std::operator<(const std::tuple<_Tps ...>&, const
std::tuple<_Elements ...>&) [with _TElements = {const int&, const long int&, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&}; _UElements =
{const place&}]':
t1_cpp14_2.cpp:40:16: required from 'main()::<lambda(const auto:1&, const auto:2&)> [with auto:1 = place; auto:2 = place]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/predefined_ops.h:143:18: required from 'constexpr bool
__gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Iterator2 =
__gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = main()::<lambda(const auto:1&, const auto:2&)>]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:81:17: required from 'void std::__move_median_to_first(_Iterator, _Iterator, _Iterator,
_Iterator, _Compare) [with _Iterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&,
const auto:2&)> >]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1921:34: required from '_RandomAccessIterator
std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*,
std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1953:38: required from 'void std::__introsort_loop(_RandomAccessIterator,
_RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Size = long long int; _Compare =
__gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1968:25: required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator,
_Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const
auto:1&, const auto:2&)> >]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:4868:18: required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter =
__gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = main()::<lambda(const auto:1&, const auto:2&)>]'
t1_cpp14_2.cpp:41:4: required from here
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/tuple:1413:7: error: static assertion failed: tuple objects can only be compared if they have equal sizes.
static_assert(sizeof...(_TElements) == sizeof...(_UElements),
^~~~~~~~~~~~~
sort(begin(places), end(places), [](const auto & a, const auto & b) {
const auto t = [](const auto & p) { return tie(p.rating_, p.price_, p.name_); };
return t(a) < tie(b);
});
45
sort(begin(places), end(places), [](const auto & a, const auto & b) {
const auto t = [](const auto & p) { return tie(p.rating_, p.price_, p.name_); };
return t(a) < tie(b);
});
Hard to read error messages
In file included from t1_cpp14_2.cpp:5:0:
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/tuple: In instantiation of 'constexpr bool std::operator<(const std::tuple<_Tps ...>&, const
std::tuple<_Elements ...>&) [with _TElements = {const int&, const long int&, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&}; _UElements =
{const place&}]':
t1_cpp14_2.cpp:40:16: required from 'main()::<lambda(const auto:1&, const auto:2&)> [with auto:1 = place; auto:2 = place]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/predefined_ops.h:143:18: required from 'constexpr bool
__gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Iterator2 =
__gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = main()::<lambda(const auto:1&, const auto:2&)>]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:81:17: required from 'void std::__move_median_to_first(_Iterator, _Iterator, _Iterator,
_Iterator, _Compare) [with _Iterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&,
const auto:2&)> >]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1921:34: required from '_RandomAccessIterator
std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*,
std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1953:38: required from 'void std::__introsort_loop(_RandomAccessIterator,
_RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Size = long long int; _Compare =
__gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1968:25: required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator,
_Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const
auto:1&, const auto:2&)> >]'
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:4868:18: required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter =
__gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = main()::<lambda(const auto:1&, const auto:2&)>]'
t1_cpp14_2.cpp:41:4: required from here
C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/tuple:1413:7: error: static assertion failed: tuple objects can only be compared if they have equal sizes.
static_assert(sizeof...(_TElements) == sizeof...(_UElements),
^~~~~~~~~~~~~
841 lines
46
No standard dependency manager and central dependency repository.
There is some activity last years: buckaroo, build2, cget, conan, conda, cpm, cppan, hunter,
vcpkg, ...
But there is no a clear winner yet.
No standard build tool.
There are lot of tools in use: bazel, build2, buckaroo, cmake, make, meson, scons, waf, ...
But there is no de-jure standard.
It seems that CMake becomes a de-facto standard.
Infrastructure from a 1980s
47
Addition of STL into C++98 made life of developers easier.
Extension of stdlib in C++11 made life yet more easier.
Another extension of stdlib in C++17 will made life yet more easier...
But C++'s stdlib still looks very poor with comparison with other popular
languages like Java, C#, Python, Ruby and so on.
Shine and poverty of C++ stdlib
48
Many developers just don't know how to use C++ safely and efficiently.
Mantra "learn C first and only then C++" is terribly wrong!
C++ as a first language? May be not a good idea.
Plain old C as a first language? It's much worse!
People's factor
49
Why does someone
need C++?
50
Procedural Programming
Object-Oriented Programming (incl. multiple inheritance)
one of the most comprehensive between statically typed OO-languages. Only Eiffel has more
advanced support for OOP.
Generic Programming (function and class templates and all that stuff...)
compile-time duck-typing and static polymorphism.
Functional Programming
All these paradigms can be easily combined in a single program.
C++ is a multiparadigm language
51
+ low resources consumption
+ total control
+ an easy access to OS and hardware.
Lot of resources were invested in optimizing C++ compiler and tools.
There are a very few alternatives with comparable expressiveness and
execution speed (if any).
High performance...
52
You can add your own "thing" and this "thing" will behave just a language's
first-class citizen.
An ability to create int_set attracted me 25 years ago...
Powerful and cheap abstraction
53
class int_set {
int * items_;
...
public:
int_set() : items_(new int[initial_capacity]) {...}
~int_set() { delete[] items_; }
...
};
int_set operator+(const int_set & a, const int_set & b) {...}
int_set operator-(const int_set & a, const int_set & b) {...}
int_set operator&(const int_set & a, const int_set & b) {...}
int_set received_items;
int_set checked_items;
...
int_set delayed_items = received_items - checked_items;
Powerful and cheap abstraction (int_set)
54
Class matrix is another classical example. Allows to write a compact and
readable code:
const unsigned N = ...;
matrix a(N,N), b(N,N), c(N,N), d(N,N);
...
matrix x = a*b + c*d;
Powerful and cheap abstraction (matrix)
55
Class matrix is another classical example. Allows to write a compact and
readable code:
const unsigned N = ...;
matrix a(N,N), b(N,N), c(N,N), d(N,N);
...
matrix x = a*b + c*d;
Powerful and cheap abstraction (matrix)
A plain C alternative:
matrix a, b, c, d;
matrix ab, cd, x;
matrix_init(&a, N, N);
matrix_init(&b, N, N);
matrix_init(&c, N, N);
matrix_init(&d, N, N);
...
matrix_init(&ab, N, N);
matrix_init(&cd, N, N);
matrix_init(&x);
matrix_mul(&a, &b, &ab);
matrix_mul(&c, &d, &cd);
matrix_add(&ab, &cd, &x);
matrix_destroy(&ab);
matrix_destroy(&cd);
...
matrix_destroy(&x);
matrix_destroy(&d);
matrix_destroy(&c);
matrix_destroy(&b);
matrix_destroy(&a);
56
Get a resource in the constructor.
allocate memory, acquire mutex, open file, create painting device, ...
Release the resource in the destructor.
destructor is called automatically when object is out of scope or destroyed manually.
We have already seen this in int_set example:
class int_set {
int * items_;
...
public:
int_set() : items_(new int[initial_capacity]) {...}
~int_set() { delete[] items_; }
RAII (Resource Acquisition Is Initialization)
57
RAII is used for different types of resources, not only memory:
void raii_example() {
ifstream file{"input.dat", ios::binary};
if(file.is_open()) {
vector<uint8_t> content = load_data(file);
...
lock_guard<mutex> lock{global_data_lock};
global_data = move(content);
global_data_updated.notify();
}
}
RAII (Resource Acquisition Is Initialization)
58
RAII is used for different types of resources, not only memory:
void raii_example() {
ifstream file{"input.dat", ios::binary};
if(file.is_open()) {
vector<uint8_t> content = load_data(file);
...
lock_guard<mutex> lock{global_data_lock};
global_data = move(content);
global_data_updated.notify();
}
}
RAII (Resource Acquisition Is Initialization)
59
C++ is great for creation of high-level domain specific tools.
High-level domain-specific tools
60
class User {
public:
...
static User fromJSON(const rapidjson::Value& doc) {
if(!doc.IsObject())
throw std::runtime_error("document should be an object");
static const char* members[] = { "id", "name", "phone", "birthday" };
for(size_t i = 0; i < sizeof(members)/sizeof(members[0]); i++)
if(!doc.HasMember(members[i])) throw std::runtime_error("missing fields");
uint64_t id = doc["id"].GetUint64();
std::string name = doc["name"].GetString();
uint64_t phone = doc["phone"].GetUint64();
Date birthday = Date::fromJSON(doc["birthday"]);
User result(id, name, phone, birthday);
return result;
}
};
Domain specific tools (JSON example)
RapidJSON
61
class User {
public:
...
template<typename Json_Io>
void json_io(Json_Io & io) {
io & json_dto::mandatory("id", _id)
& json_dto::mandatory("name", _name)
& json_dto::mandatory("birthday", _birthday)
& json_dto::mandatory("phone", _phone);
}
};
Domain specific tools (JSON example)
RapidJSON + json_dto
62
How to use C++
safely and
efficiently?
63
Use only that you know.
Any safe subset of C++ is still C++.
Common sense rulezzz!
64
There are a lot of for different application areas:
– C++ Core Guidelines;
– guidelines from famous companies or projects (Google's, Boost's,
Mozilla's, Bloomberg's, CERT's, ...);
– industry-specific standard and/or guidelines (Joint Strike Fighter Air
Vehicle C++ Coding Standards, MISRA C++, High Integrity C++,...)
Use guidelines
65
Static code analyzers:
– cppcheck;
– clang static analyzer;
– Coverity;
– PVS-Studio.
Sanitizers (GCC, clang):
– address;
– thread;
– leak;
– undefined.
Compiler flags like -Wall, -Weverything and -Werror are your friends!
Use analyzers and sanitizers
66
/// Open a device and get handle for it.
///
/// attention A dynamically allocated object returned. Caller must deallocate it.
device * open_device(
/// Name of device to be created.
const char * dev_name,
/// Creation options.
device_options options);
...
auto dev = open_device("lpt1", defaults);
dev->write(...);
...
delete dev;
Use right abstractions (1)
67
/// Open a device and get handle for it.
unique_ptr<device> open_device(
/// Name of device to be created.
const char * dev_name,
/// Creation options.
device_options options);
...
auto dev = open_device("lpt1", defaults);
dev->write(...);
...
Use right abstractions (2)
68
Many developers abandon type-safe API if it requires a lot of boilerplate
code:
ostream & operator<<(ostream & o, const place & p) {
o << setw(20) << left << p.name_ << "[" << p.rating_ << "]"
<< setw(7) << right << p.price_;
return o;
}
Use right libraries (type safety)
69
And use something more "useful" and/or "powerful":
ostream & operator<<(ostream & o, const place & p) {
char buf[30];
snprintf(buf, sizeof(buf), "%-20s[%d]%7d", p.name_, p.rating_, p.price_);
return (o << buf);
}
Use right libraries (type safety)
70
And use something more "useful" and/or "powerful":
ostream & operator<<(ostream & o, const place & p) {
char buf[30];
snprintf(buf, sizeof(buf), "%-20s[%d]%7d", p.name_, p.rating_, p.price_);
return (o << buf);
}
Use right libraries (type safety)
30 characters required for textual
representation. But addition character is
necessary for terminating 0-symbol.
place::price_ is unsigned long, "%7ld"
must be used instead of "%7d".
place::name_ is std::string, not
char*, place.name_.c_str() must be
used.
71
There are powerful and type-safe libraries. fmtlib as an example:
#include <fmt/format.h>
#include <fmt/ostream.h>
ostream & operator<<(ostream & o, const place & p) {
fmt::print(o, "{:<20}[{}]{:7}", p.name_, p.rating_, p.price_);
return o;
}
Use right libraries (type safety)
72
How many lines of modern C++ are necessary to write the simplest HTTP-
server?
A server that responds "Hello, world" for all requests?
Use right libraries (simplicity)
73
Simplest HTTP-server in Boost.Beast:
Use right libraries (simplicity)
#include <boost/program_options.hpp>
#include <iostream>
#include <thread>
#include <mutex>
#include <boost/beast/http.hpp>
#include <boost/beast/core/handler_ptr.hpp>
#include <boost/beast/core/multi_buffer.hpp>
#include <boost/beast/core/flat_buffer.hpp>
#include <boost/asio.hpp>
#include <app_args.hpp>
using namespace boost::beast;
using namespace boost::beast::http;
class http_server_t
{
using endpoint_type = boost::asio::ip::tcp::endpoint;
using address_type = boost::asio::ip::address;
using socket_type = boost::asio::ip::tcp::socket;
using req_type = request<string_body>;
using resp_type = response<string_body>;
endpoint_type ep_;
boost::asio::io_service ios_;
boost::asio::ip::tcp::acceptor acceptor_;
socket_type sock_;
public:
http_server_t(endpoint_type const& ep )
: ep_(ep), acceptor_(ios_), sock_(ios_) {}
void run()
{
acceptor_.open(ep_.protocol());
acceptor_.bind(ep_);
acceptor_.listen(
boost::asio::socket_base::max_connections);
acceptor_.async_accept(sock_,
std::bind(&http_server_t::on_accept, this,
std::placeholders::_1));
boost::asio::signal_set break_signals{ ios_, SIGINT };
break_signals.async_wait(
[&]( const auto & ec, int ){
if( !ec )
{
error_code ec;
ios_.dispatch( [&]{ acceptor_.close(ec); });
}
} );
ios_.run();
}
private:
template<class Stream, class Handler, bool isRequest, class Body, class Fields>
class write_op
{
struct data
{
bool cont;
Stream& s;
message<isRequest, Body, Fields> m;
data(Handler& handler, Stream& s_, message<isRequest, Body, Fields>&& m_)
: s(s_), m(std::move(m_))
{
using boost::asio::asio_handler_is_continuation;
cont = asio_handler_is_continuation(std::addressof(handler));
}
};
handler_ptr<data, Handler> d_;
public:
write_op(write_op&&) = default;
write_op(write_op const&) = default;
template<class DeducedHandler, class... Args>
write_op(DeducedHandler&& h, Stream& s, Args&&... args)
: d_(std::forward<DeducedHandler>(h),
s, std::forward<Args>(args)...)
{
(*this)(error_code{}, false);
}
void operator()(error_code ec, bool again = true)
{
auto& d = *d_;
d.cont = d.cont || again;
if(! again)
{
boost::beast::http::async_write(d.s, d.m, std::move(*this));
return;
}
d_.invoke(ec);
}
friend void* asio_handler_allocate(std::size_t size, write_op* op)
{
using boost::asio::asio_handler_allocate;
return asio_handler_allocate( size, std::addressof(op->d_.handler()));
}
friend void asio_handler_deallocate(void* p, std::size_t size, write_op* op)
{
using boost::asio::asio_handler_deallocate;
asio_handler_deallocate( p, size, std::addressof(op->d_.handler()));
}
friend bool asio_handler_is_continuation(write_op* op)
{
return op->d_->cont;
}
template<class Function>
friend void asio_handler_invoke(Function&& f, write_op* op)
{
using boost::asio::asio_handler_invoke;
asio_handler_invoke( f, std::addressof(op->d_.handler()));
}
};
template<class Stream, bool isRequest, class Body, class Fields, class DeducedHandler>
static void async_write(
Stream& stream,
message<isRequest, Body, Fields>&& msg,
DeducedHandler&& handler)
{
write_op<Stream, typename std::decay<DeducedHandler>::type,
isRequest, Body, Fields>{std::forward<DeducedHandler>(
handler), stream, std::move(msg)};
}
class peer : public std::enable_shared_from_this<peer>
{
flat_buffer sb_{ 1024 };
socket_type sock_;
req_type req_;
public:
peer(peer&&) = default;
peer(peer const&) = default;
peer& operator=(peer&&) = delete;
peer& operator=(peer const&) = delete;
peer(socket_type&& sock)
: sock_(std::move(sock)) {}
void run()
{
do_read();
}
void do_read()
{
async_read(sock_, sb_, req_,
std::bind(&peer::on_read, this->shared_from_this(),
std::placeholders::_1));
}
void on_read(error_code const& ec)
{
if(!ec)
{
resp_type res;
res.result(status::ok);
res.version( req_.version() );
res.insert(field::server, "Beast");
res.insert(field::content_type, "text/plain; charset=utf-8");
res.keep_alive( true );
res.body() = "Hello, World!";
res.prepare_payload();
async_write(sock_, std::move(res),
std::bind(&peer::on_write, this->shared_from_this(),
std::placeholders::_1));
}
}
void on_write(error_code ec)
{
if(!ec)
do_read();
}
};
void on_accept(error_code const& ec)
{
if(!acceptor_.is_open())
return;
if(!ec)
{
socket_type sock(std::move(sock_));
std::make_shared<peer>(std::move(sock))->run();
}
acceptor_.async_accept(sock_,
std::bind(&http_server_t::on_accept, this,
std::placeholders::_1));
}
};
int main()
{
using endpoint_type = boost::asio::ip::tcp::endpoint;
using address_type = boost::asio::ip::address;
endpoint_type ep{address_type::from_string( "127.0.0.1" ), 8080 };
http_server_t server{ ep };
server.run();
return 0;
}
74
Simplest HTTP-server in RESTinio:
#include <restinio/all.hpp>
int main()
{
restinio::run(
restinio::on_this_thread()
.port(8080)
.address("localhost")
.request_handler([](auto req) {
return req->create_response().set_body("Hello, World!").done();
}));
return 0;
}
Use right libraries (simplicity)
75
There are many different C++ libraries for different areas. Some of them:
Generic: Boost, Folly, Abseil, BDE; Networking: Asio, ACE, POCO; GUI: Qt,
FLTK, wxWidgets, nana; i18n: ICU; Linear algebra: Boost.uBLAS, Eigen,
Blitz++; Concurrency+Parallel computing: TBB, HPX, Thrust; Lock-free:
libcds; Actors: QP/C++, CAF, SObjectizer; REST: C++ REST SDK, RestBed,
Pistache, RESTinio; Web: CppCMS, Tntnet, TreeFrog, Wt; JSON: RapidJSON,
json; RDBMS: OTL, SOCI, sqlpp11; Testing: Boost.Test, gTest, Catch2,
doctest; ...
Use right libraries
Useful links collections: Awesome C++ Libraries (github), Awesome C++ Libraries
(libhunt), Non-ANSI/ISO C++ Libs on cppreference.com
76
Where C++ can be
used now?
77
IT-landscape has changed but there are still many areas where high
performance and low resource consumptions matter.
Smartphones and mobile development are here. Battery life matters.
High diversity of devices in use: PC, laptops/netbooks, tablets, smartphones,
smart watches, smart TVs, game consoles, ...
Big server farms.
Free lunch is over. It's not an easy to take a performance gain now.
The return of interest in native code apps.
2011-2017: what's changed?
78
C++ Futures on Instagram: high-performing recommendation service was
rewritten in C++.
number of servers reduced from 720 to 38.
Speedup PHP at Facebook: HipHop (PHP-to-C++ transpiler) and HHVM
(HipHop Virtual Machine).
Some examples. Server-side
79
ScyllaDB: a high performance drop-in replacement for Cassandra.
10x better performance on high-end hardware, 1.5x-3x better on smaller machines.
Quantcast File System: a high performance alternative to HDFS (Hadoop
Distributed File System) written in C++.
50% space reduction, +75% write and +45% read throughput.
Some examples. Middleware
80
Doodle Kindom: cross-plaform games with kernel in C++.
works on iPhone, iPad, Windows, MacOS, NOOK.
Oncam: a videochat system for iOS+Android with kernel in C++.
supports videochat up to 6 participant with at least 15FPS.
Some examples. Mobile
81
High performance computing
– weather forecasting, molecular modeling, physic simulation, big-data, machine learning, ...
Low resource consumption
– mobile application, internet of things, ...
System programming (and around)
– OS kernels, drivers and utilities, middleware, compilers, antiviruses, ...
Real-time and embedded systems
– SCADA, industrial internet of things, avionics, automotive, finance, telecom, defense, ...
Complex desktop applications
– CADs, photoshop, AAA games, browsers, office apps, ...
Cross-platform apps
– app's kernel in C++ + GUI in native technology (Dropbox's jinie), ...
Legacy
Where C++ can be used now?
82
There is no place for quick-
and-dirty solutions!
What is in common?
83
Who is trying to eat
C++ now?
84
Java and C#:
It is not actual anymore :) Java and C# already ate everything they could.
plain C:
It is actual again. Suddenly?
Go:
Shines in its very narrow niche. Attracts much more Python/Ruby developers than C++ devs.
Rust:
The only real modern alternative to C++ now. But it is a hard question.
Main alternatives
85
Ada:
Very strong competitor for embedded and real-time areas. Almost unknown in East Europe.
D:
It's too late. Lack of popularity and presence of GC.
Swift:
Almost nonexistent outside the Apple's ecosystem.
Some other alternatives
86
C++ is a community-
driven language
87
There is no commercial force behind it (like Oracle for Java, Microsoft for
C#, JetBrains for Kotlin and so on).
If you need something in C++ you can propose it: https://stdcpp.ru/
C++ is community driven language
88
Thank you!
89
Questions?
stiffstream.com
eao197 at stiffstream.com

Weitere ähnliche Inhalte

Was ist angesagt?

Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsAlexander Granin
 
The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202Mahmoud Samir Fayed
 
How to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJITHow to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJITEgor Bogatov
 
Bartosz Milewski, “Re-discovering Monads in C++”
Bartosz Milewski, “Re-discovering Monads in C++”Bartosz Milewski, “Re-discovering Monads in C++”
Bartosz Milewski, “Re-discovering Monads in C++”Platonov Sergey
 
Computer Graphics Lab
Computer Graphics LabComputer Graphics Lab
Computer Graphics LabNeil Mathew
 
Beyond tf idf why, what & how
Beyond tf idf why, what & howBeyond tf idf why, what & how
Beyond tf idf why, what & howlucenerevolution
 
Java8 stream
Java8 streamJava8 stream
Java8 streamkoji lin
 
Operator overloading2
Operator overloading2Operator overloading2
Operator overloading2zindadili
 
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Romain Francois
 
Modern C++ Lunch and Learn
Modern C++ Lunch and LearnModern C++ Lunch and Learn
Modern C++ Lunch and LearnPaul Irwin
 
PVS-Studio team experience: checking various open source projects, or mistake...
PVS-Studio team experience: checking various open source projects, or mistake...PVS-Studio team experience: checking various open source projects, or mistake...
PVS-Studio team experience: checking various open source projects, or mistake...Andrey Karpov
 
44CON 2013 - The Forger's Art: Exploiting XML Digital Signature Implementatio...
44CON 2013 - The Forger's Art: Exploiting XML Digital Signature Implementatio...44CON 2013 - The Forger's Art: Exploiting XML Digital Signature Implementatio...
44CON 2013 - The Forger's Art: Exploiting XML Digital Signature Implementatio...44CON
 
COMPUTER GRAPHICS LAB MANUAL
COMPUTER GRAPHICS LAB MANUALCOMPUTER GRAPHICS LAB MANUAL
COMPUTER GRAPHICS LAB MANUALVivek Kumar Sinha
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4Abed Bukhari
 

Was ist angesagt? (20)

Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
 
Advance java
Advance javaAdvance java
Advance java
 
The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202The Ring programming language version 1.8 book - Part 94 of 202
The Ring programming language version 1.8 book - Part 94 of 202
 
How to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJITHow to add an optimization for C# to RyuJIT
How to add an optimization for C# to RyuJIT
 
Bartosz Milewski, “Re-discovering Monads in C++”
Bartosz Milewski, “Re-discovering Monads in C++”Bartosz Milewski, “Re-discovering Monads in C++”
Bartosz Milewski, “Re-discovering Monads in C++”
 
Computer hw1
Computer hw1Computer hw1
Computer hw1
 
Computer Graphics Lab
Computer Graphics LabComputer Graphics Lab
Computer Graphics Lab
 
Lec06
Lec06Lec06
Lec06
 
Beyond tf idf why, what & how
Beyond tf idf why, what & howBeyond tf idf why, what & how
Beyond tf idf why, what & how
 
Bind me if you can
Bind me if you canBind me if you can
Bind me if you can
 
Computer graphics
Computer graphicsComputer graphics
Computer graphics
 
Java8 stream
Java8 streamJava8 stream
Java8 stream
 
Operator overloading2
Operator overloading2Operator overloading2
Operator overloading2
 
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Rcpp: Seemless R and C++
Rcpp: Seemless R and C++
 
Modern C++ Lunch and Learn
Modern C++ Lunch and LearnModern C++ Lunch and Learn
Modern C++ Lunch and Learn
 
PVS-Studio team experience: checking various open source projects, or mistake...
PVS-Studio team experience: checking various open source projects, or mistake...PVS-Studio team experience: checking various open source projects, or mistake...
PVS-Studio team experience: checking various open source projects, or mistake...
 
44CON 2013 - The Forger's Art: Exploiting XML Digital Signature Implementatio...
44CON 2013 - The Forger's Art: Exploiting XML Digital Signature Implementatio...44CON 2013 - The Forger's Art: Exploiting XML Digital Signature Implementatio...
44CON 2013 - The Forger's Art: Exploiting XML Digital Signature Implementatio...
 
COMPUTER GRAPHICS LAB MANUAL
COMPUTER GRAPHICS LAB MANUALCOMPUTER GRAPHICS LAB MANUAL
COMPUTER GRAPHICS LAB MANUAL
 
Permute
PermutePermute
Permute
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
 

Ähnlich wie GECon 2017: C++ - a Monster that no one likes but that will outlast them all

25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазах25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазахcorehard_by
 
Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»SpbDotNet Community
 
25 Years of C++ History Flashed in Front of My Eyes
25 Years of C++ History Flashed in Front of My Eyes25 Years of C++ History Flashed in Front of My Eyes
25 Years of C++ History Flashed in Front of My EyesYauheni Akhotnikau
 
Computer Vision using Ruby and libJIT - RubyConf 2009
Computer Vision using Ruby and libJIT - RubyConf 2009Computer Vision using Ruby and libJIT - RubyConf 2009
Computer Vision using Ruby and libJIT - RubyConf 2009Jan Wedekind
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
C++ process new
C++ process newC++ process new
C++ process new敬倫 林
 
Getting Functional with Scala
Getting Functional with ScalaGetting Functional with Scala
Getting Functional with ScalaJorge Paez
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116Paulo Morgado
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6FITC
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionHans Höchtl
 
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Romain Francois
 
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Romain Francois
 
C++ lectures all chapters in one slide.pptx
C++ lectures all chapters in one slide.pptxC++ lectures all chapters in one slide.pptx
C++ lectures all chapters in one slide.pptxssuser3cbb4c
 
CBSE Question Paper Computer Science with C++ 2011
CBSE Question Paper Computer Science with C++ 2011CBSE Question Paper Computer Science with C++ 2011
CBSE Question Paper Computer Science with C++ 2011Deepak Singh
 

Ähnlich wie GECon 2017: C++ - a Monster that no one likes but that will outlast them all (20)

25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазах25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазах
 
Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»
 
25 Years of C++ History Flashed in Front of My Eyes
25 Years of C++ History Flashed in Front of My Eyes25 Years of C++ History Flashed in Front of My Eyes
25 Years of C++ History Flashed in Front of My Eyes
 
Computer Vision using Ruby and libJIT - RubyConf 2009
Computer Vision using Ruby and libJIT - RubyConf 2009Computer Vision using Ruby and libJIT - RubyConf 2009
Computer Vision using Ruby and libJIT - RubyConf 2009
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
TechTalk - Dotnet
TechTalk - DotnetTechTalk - Dotnet
TechTalk - Dotnet
 
C++ process new
C++ process newC++ process new
C++ process new
 
Getting Functional with Scala
Getting Functional with ScalaGetting Functional with Scala
Getting Functional with Scala
 
C to perl binding
C to perl bindingC to perl binding
C to perl binding
 
Groovy
GroovyGroovy
Groovy
 
Pointers+(2)
Pointers+(2)Pointers+(2)
Pointers+(2)
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Summary of C++17 features
Summary of C++17 featuresSummary of C++17 features
Summary of C++17 features
 
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Rcpp: Seemless R and C++
Rcpp: Seemless R and C++
 
Metarhia KievJS 22-Feb-2018
Metarhia KievJS 22-Feb-2018Metarhia KievJS 22-Feb-2018
Metarhia KievJS 22-Feb-2018
 
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++Rcpp: Seemless R and C++
Rcpp: Seemless R and C++
 
C++ lectures all chapters in one slide.pptx
C++ lectures all chapters in one slide.pptxC++ lectures all chapters in one slide.pptx
C++ lectures all chapters in one slide.pptx
 
CBSE Question Paper Computer Science with C++ 2011
CBSE Question Paper Computer Science with C++ 2011CBSE Question Paper Computer Science with C++ 2011
CBSE Question Paper Computer Science with C++ 2011
 

Mehr von Yauheni Akhotnikau

arataga. SObjectizer and RESTinio in action: a real-world example
arataga. SObjectizer and RESTinio in action: a real-world examplearataga. SObjectizer and RESTinio in action: a real-world example
arataga. SObjectizer and RESTinio in action: a real-world exampleYauheni Akhotnikau
 
Actor Model and C++: what, why and how? (March 2020 Edition)
Actor Model and C++: what, why and how? (March 2020 Edition)Actor Model and C++: what, why and how? (March 2020 Edition)
Actor Model and C++: what, why and how? (March 2020 Edition)Yauheni Akhotnikau
 
What is SObjectizer 5.7 (at v.5.7.0)
What is SObjectizer 5.7 (at v.5.7.0)What is SObjectizer 5.7 (at v.5.7.0)
What is SObjectizer 5.7 (at v.5.7.0)Yauheni Akhotnikau
 
What is SObjectizer 5.6 (at v.5.6.0)
What is SObjectizer 5.6 (at v.5.6.0)What is SObjectizer 5.6 (at v.5.6.0)
What is SObjectizer 5.6 (at v.5.6.0)Yauheni Akhotnikau
 
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...Yauheni Akhotnikau
 
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...Shrimp: A Rather Practical Example Of Application Development With RESTinio a...
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...Yauheni Akhotnikau
 
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...Yauheni Akhotnikau
 
Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?Yauheni Akhotnikau
 
Dive into SObjectizer 5.5. Tenth part: Mutable Messages
Dive into SObjectizer 5.5. Tenth part: Mutable MessagesDive into SObjectizer 5.5. Tenth part: Mutable Messages
Dive into SObjectizer 5.5. Tenth part: Mutable MessagesYauheni Akhotnikau
 
Actor Model and C++: what, why and how?
Actor Model and C++: what, why and how?Actor Model and C++: what, why and how?
Actor Model and C++: what, why and how?Yauheni Akhotnikau
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Yauheni Akhotnikau
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Yauheni Akhotnikau
 
Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Yauheni Akhotnikau
 
Dive into SObjectizer 5.5. Ninth Part: Message Chains
Dive into SObjectizer 5.5. Ninth Part: Message ChainsDive into SObjectizer 5.5. Ninth Part: Message Chains
Dive into SObjectizer 5.5. Ninth Part: Message ChainsYauheni Akhotnikau
 
Dive into SObjectizer 5.5. Eighth Part: Dispatchers
Dive into SObjectizer 5.5. Eighth Part: DispatchersDive into SObjectizer 5.5. Eighth Part: Dispatchers
Dive into SObjectizer 5.5. Eighth Part: DispatchersYauheni Akhotnikau
 
What's new in SObjectizer 5.5.9
What's new in SObjectizer 5.5.9What's new in SObjectizer 5.5.9
What's new in SObjectizer 5.5.9Yauheni Akhotnikau
 
Dive into SObjectizer 5.5. Seventh part: Message Limits
Dive into SObjectizer 5.5. Seventh part: Message LimitsDive into SObjectizer 5.5. Seventh part: Message Limits
Dive into SObjectizer 5.5. Seventh part: Message LimitsYauheni Akhotnikau
 
Dive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Dive into SObjectizer-5.5. Sixth part: Synchronous InteractionDive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Dive into SObjectizer-5.5. Sixth part: Synchronous InteractionYauheni Akhotnikau
 
Dive into SObjectizer 5.5. Fifth part: Timers
Dive into SObjectizer 5.5. Fifth part: TimersDive into SObjectizer 5.5. Fifth part: Timers
Dive into SObjectizer 5.5. Fifth part: TimersYauheni Akhotnikau
 
What’s new in SObjectizer 5.5.8
What’s new in SObjectizer 5.5.8What’s new in SObjectizer 5.5.8
What’s new in SObjectizer 5.5.8Yauheni Akhotnikau
 

Mehr von Yauheni Akhotnikau (20)

arataga. SObjectizer and RESTinio in action: a real-world example
arataga. SObjectizer and RESTinio in action: a real-world examplearataga. SObjectizer and RESTinio in action: a real-world example
arataga. SObjectizer and RESTinio in action: a real-world example
 
Actor Model and C++: what, why and how? (March 2020 Edition)
Actor Model and C++: what, why and how? (March 2020 Edition)Actor Model and C++: what, why and how? (March 2020 Edition)
Actor Model and C++: what, why and how? (March 2020 Edition)
 
What is SObjectizer 5.7 (at v.5.7.0)
What is SObjectizer 5.7 (at v.5.7.0)What is SObjectizer 5.7 (at v.5.7.0)
What is SObjectizer 5.7 (at v.5.7.0)
 
What is SObjectizer 5.6 (at v.5.6.0)
What is SObjectizer 5.6 (at v.5.6.0)What is SObjectizer 5.6 (at v.5.6.0)
What is SObjectizer 5.6 (at v.5.6.0)
 
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...
 
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...Shrimp: A Rather Practical Example Of Application Development With RESTinio a...
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...
 
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
 
Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?
 
Dive into SObjectizer 5.5. Tenth part: Mutable Messages
Dive into SObjectizer 5.5. Tenth part: Mutable MessagesDive into SObjectizer 5.5. Tenth part: Mutable Messages
Dive into SObjectizer 5.5. Tenth part: Mutable Messages
 
Actor Model and C++: what, why and how?
Actor Model and C++: what, why and how?Actor Model and C++: what, why and how?
Actor Model and C++: what, why and how?
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?
 
Dive into SObjectizer 5.5. Ninth Part: Message Chains
Dive into SObjectizer 5.5. Ninth Part: Message ChainsDive into SObjectizer 5.5. Ninth Part: Message Chains
Dive into SObjectizer 5.5. Ninth Part: Message Chains
 
Dive into SObjectizer 5.5. Eighth Part: Dispatchers
Dive into SObjectizer 5.5. Eighth Part: DispatchersDive into SObjectizer 5.5. Eighth Part: Dispatchers
Dive into SObjectizer 5.5. Eighth Part: Dispatchers
 
What's new in SObjectizer 5.5.9
What's new in SObjectizer 5.5.9What's new in SObjectizer 5.5.9
What's new in SObjectizer 5.5.9
 
Dive into SObjectizer 5.5. Seventh part: Message Limits
Dive into SObjectizer 5.5. Seventh part: Message LimitsDive into SObjectizer 5.5. Seventh part: Message Limits
Dive into SObjectizer 5.5. Seventh part: Message Limits
 
Dive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Dive into SObjectizer-5.5. Sixth part: Synchronous InteractionDive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Dive into SObjectizer-5.5. Sixth part: Synchronous Interaction
 
Dive into SObjectizer 5.5. Fifth part: Timers
Dive into SObjectizer 5.5. Fifth part: TimersDive into SObjectizer 5.5. Fifth part: Timers
Dive into SObjectizer 5.5. Fifth part: Timers
 
What’s new in SObjectizer 5.5.8
What’s new in SObjectizer 5.5.8What’s new in SObjectizer 5.5.8
What’s new in SObjectizer 5.5.8
 

Kürzlich hochgeladen

Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfCionsystems
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....ShaimaaMohamedGalal
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 

Kürzlich hochgeladen (20)

Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdf
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 

GECon 2017: C++ - a Monster that no one likes but that will outlast them all

  • 1. C++ ‒ a Monster that no one likes but that will outlast them all Yauheni Akhotnikau
  • 2. 2 Started programming somewhere in 1990. The first meet with C++ in 1991. C++ is the main tool since 1992 with a few short pauses. Used some other languages. For example: Pascal, Visual Basic, Java, Ruby, D, Eiffel, Scala. I can use C++ without a pain but I don't think that C++ is the greatest language ever. A few words about me
  • 3. 3 A bit of C++ evolution history. Why C++ became popular and why C++ started to lose its popularity. Why C++ is a Monster? If C ++ is a monster, then why does someone need C++? How to use C++ safely and efficiently? Where and when C++ can be used. If it can... Pressure to C++ from competitors. Real and imaginary. Agenda
  • 4. 4 The history and evolution of C++ (and some taste of C++)
  • 5. 5 By the help of a simple demo application: • there is a collection of struct place (each struct contains name, price and rating); • sort this collection by rating, then by price, then by name. And then print the collection after sorting; • sort this collection by name, then print it. A way to see the evolution in examples
  • 6. 6 Work on C++ began in 1979. Bjarne Stroustrup decided to build a language with power of Simula 67 and efficiency of C. The first name of the new language was "C with Classes". Name C++ appeared in 1983. The first public release in 1985. The birth of C++
  • 7. 7 struct place { char * name_; long price_; int rating_; place() : name_(0) {} place(const char * name, long price, int rating) : name_(copy_name(name)), price_(price), rating_(rating) {} place(const place & o) : name_(copy_name(o.name_)), price_(o.price_), rating_(o.rating_) {} ~place() { delete[] name_; } place & operator=(const place & o) { char * copy = copy_name(o.name_); delete[] name_; name_ = copy; price_ = o.price_; rating_ = o.rating_; return *this; } static char * copy_name(const char * src) { char * r = 0; if(src) { r = new char[strlen(src) + 1]; strcpy(r, src); } return r; } }; A taste of ancient C++ (pre-C++98)
  • 8. 8 ostream & operator<<(ostream & to, const place & p) { to << setw(20) << left << p.name_ << "[" << p.rating_ << "]" << setw(7) << right << p.price_; return to; } void print(const place * places, size_t count) { for(size_t i = 0; i != count; ++i) cout << places[i] << endl; cout << endl; } A taste of ancient C++ (pre-C++98)
  • 9. 9 int compare_by_rating_price_name(const void * av, const void * bv) { const place & a = *(const place *)av; const place & b = *(const place *)bv; int result; if(a.rating_ < b.rating_) result = -1; else { if(a.rating_ == b.rating_) { if(a.price_ < b.price_) result = -1; else { if(a.price_ == b.price_) { result = strcmp(a.name_, b.name_); } else result = 1; } } else result = 1; } return result; } int compare_by_name(const void * av, const void * bv) { const place & a = *(const place *)av; const place & b = *(const place *)bv; return strcmp(a.name_, b.name_); } A taste of ancient C++ (pre-C++98)
  • 10. 10 void get_places(place *& places, size_t & count) { places = new place[7]; places[0] = place("Moscow", 1500, 3); places[1] = place("St. Petersburg", 1300, 5); places[2] = place("Minsk", 500, 4); places[3] = place("Tokyo", 3500, 4); places[4] = place("Sydney", 5000, 3); places[5] = place("Paris", 3000, 5); places[6] = place("London", 3500, 4); count = 7; } A taste of ancient C++ (pre-C++98)
  • 11. 11 int main() { place * places; size_t count; get_places(places, count); qsort(places, count, sizeof(place), compare_by_rating_price_name); print(places, count); qsort(places, count, sizeof(place), compare_by_name); print(places, count); delete[] places; } A taste of ancient C++ (pre-C++98)
  • 12. 12 Moscow [3] 1500 Sydney [3] 5000 Minsk [4] 500 London [4] 3500 Tokyo [4] 3500 St. Petersburg [5] 1300 Paris [5] 3000 London [4] 3500 Minsk [4] 500 Moscow [3] 1500 Paris [5] 3000 St. Petersburg [5] 1300 Sydney [3] 5000 Tokyo [4] 3500 A taste of ancient C++ (pre-C++98)
  • 13. 13 1985-1995: fast evolution: – multiple inheritance, const-methods, protected keyword, namespaces, templates, exceptions, RTTI, explicit keyword, ... 1990: ANSI/ISO standardization started. 1992: Alex Stepanov started STL. 1994-1998: process of inclusion of STL into the standard. 1998: the first international standard ‒ C++98. 2003: an updated standard ‒ C++03. 1985-2003: main milestones
  • 14. 14 using namespace std; struct place { string name_; long price_; int rating_; place() {} place(const char * name, float price, int rating) : name_(name), price_(price), rating_(rating) {} }; A taste of old C++ (C++98)
  • 15. 15 ostream & operator<<(ostream & to, const place & p) { to << setw(20) << left << p.name_ << "[" << p.rating_ << "]" << setw(7) << right << p.price_; return to; } template<class C> void print(const C & places) { for(typename C::const_iterator i = places.begin(); i != places.end(); ++i) cout << *i << endl; cout << endl; } A taste of old C++ (C++98)
  • 16. 16 bool compare_by_rating_price_name(const place & a, const place & b) { bool result = false; if(a.rating_ < b.rating_) result = true; else if(a.rating_ == b.rating_) { if(a.price_ < b.price_) result = true; else if(a.price_ == b.price_) result = (a.name_ < b.name_); } return result; } bool compare_by_name(const place & a, const place & b) { return a.name_ < b.name_; } A taste of old C++ (C++98)
  • 17. 17 vector<place> get_places() { vector<place> places; places.push_back(place("Moscow", 1500, 3)); places.push_back(place("St. Petersburg", 1300, 5)); places.push_back(place("Minsk", 500, 4)); places.push_back(place("Tokyo", 3500, 4)); places.push_back(place("Sydney", 5000, 3)); places.push_back(place("Paris", 3000, 5)); places.push_back(place("London", 3500, 4)); return places; } A taste of old C++ (C++98)
  • 18. 18 int main() { vector<place> places = get_places(); sort(places.begin(), places.end(), compare_by_rating_price_name); print(places); sort(places.begin(), places.end(), compare_by_name); print(places); } A taste of old C++ (C++98)
  • 19. 19 2003-2011: long-term construction under the name of C++0x. 2011: C++11 released. It's a very different beast! many, many language improvements; significant extension of stdlib; 2014: C++14 released. A minor update with some very useful features. 2017: draft of C++17. An important update with lot of new features and additions to stdlib. 2017: work on C++20 started. 2003-2017: main milestones
  • 20. 20 #include <fmt/format.h> #include <fmt/ostream.h> using namespace std; struct place { string name_; long price_; int rating_; }; A taste of modern C++ (C++17)
  • 21. 21 ostream & operator<<(ostream & to, const place & p) { fmt::print(to, "{:<20}[{}]{:7}", p.name_, p.rating_, p.price_); return to; } void print(auto & places) { for(const auto & p : places) cout << p << endl; cout << endl; } A taste of modern C++ (C++17)
  • 22. 22 bool compare_by_rating_price_name(const place & a, const place & b) { return tie(a.rating_, a.price_, a.name_) < tie(b.rating_, b.price_, b.name_); } bool compare_by_name(const place & a, const place & b) { return a.name_ < b.name_; } A taste of modern C++ (C++17)
  • 23. 23 vector<place> get_places() { return { {"Moscow", 1500, 3}, {"St. Petersburg", 1300, 5}, {"Minsk", 500, 4}, {"Tokyo", 3500, 4}, {"Sydney", 5000, 3}, {"Paris", 3000, 5}, {"London", 3500, 4} }; } A taste of modern C++ (C++17)
  • 24. 24 int main() { auto places = get_places(); sort(begin(places), end(places), compare_by_rating_price_name); print(places); sort(begin(places), end(places), compare_by_name); print(places); } A taste of modern C++ (C++17)
  • 25. 25 A shot look to the full demo source code… 1985-2017: the comparison
  • 26. 26 #include <iostream.h> #include <iomanip.h> #include <string.h> #include <stdlib.h> struct place { char * name_; long price_; int rating_; place() : name_(0) {} place(const char * name, long price, int rating) : name_(copy_name(name)), price_(price), rating_(rating) {} place(const place & o) : name_(copy_name(o.name_)), price_(o.price_), rating_(o.rating_) {} ~place() { delete[] name_; } place & operator=(const place & o) { char * copy = copy_name(o.name_); delete[] name_; name_ = copy; price_ = o.price_; rating_ = o.rating_; return *this; } static char * copy_name(const char * src) { char * r = 0; if(src) { r = new char[strlen(src) + 1]; strcpy(r, src); } return r; } }; ostream & operator<<(ostream & to, const place & p) { to << setw(20) << left << p.name_ << "[" << p.rating_ << "]" << setw(7) << right << p.price_; return to; } void print(const place * places, size_t count) { for(size_t i = 0; i != count; ++i) cout << places[i] << endl; cout << endl; } int compare_by_rating_price_name(const void * av, const void * bv) { const place & a = *(const place *)av; const place & b = *(const place *)bv; int result; if(a.rating_ < b.rating_) result = -1; else { if(a.rating_ == b.rating_) { if(a.price_ < b.price_) result = -1; else { if(a.price_ == b.price_) { result = strcmp(a.name_, b.name_); } else result = 1; } } else result = 1; } return result; } int compare_by_name(const void * av, const void * bv) { const place & a = *(const place *)av; const place & b = *(const place *)bv; return strcmp(a.name_, b.name_); } void get_places(place *& places, size_t & count) { places = new place[7]; places[0] = place("Moscow", 1500, 3); places[1] = place("St. Petersburg", 1300, 5); places[2] = place("Minsk", 500, 4); places[3] = place("Tokyo", 3500, 4); places[4] = place("Sydney", 5000, 3); places[5] = place("Paris", 3000, 5); places[6] = place("London", 3500, 4); count = 7; } int main() { place * places; size_t count; get_places(places, count); qsort(places, count, sizeof(place), compare_by_rating_price_name); print(places, count); qsort(places, count, sizeof(place), compare_by_name); print(places, count); delete[] places; } A taste of… Full text of pre-C++98 demo
  • 27. 27 #include <algorithm> #include <iostream> #include <iomanip> #include <string> #include <vector> using namespace std; struct place { string name_; long price_; int rating_; place() {} place(const char * name, float price, int rating) : name_(name), price_(price), rating_(rating) {} }; ostream & operator<<(ostream & to, const place & p) { to << setw(20) << left << p.name_ << "[" << p.rating_ << "]" << setw(7) << right << p.price_; return to; } template<class C> void print(const C & places) { for(typename C::const_iterator i = places.begin(); i != places.end(); ++i) cout << *i << endl; cout << endl; } bool compare_by_rating_price_name(const place & a, const place & b) { bool result = false; if(a.rating_ < b.rating_) result = true; else if(a.rating_ == b.rating_) { if(a.price_ < b.price_) result = true; else if(a.price_ == b.price_) result = (a.name_ < b.name_); } return result; } bool compare_by_name(const place & a, const place & b) { return a.name_ < b.name_; } vector<place> get_places() { vector<place> places; places.push_back(place("Moscow", 1500, 3)); places.push_back(place("St. Petersburg", 1300, 5)); places.push_back(place("Minsk", 500, 4)); places.push_back(place("Tokyo", 3500, 4)); places.push_back(place("Sydney", 5000, 3)); places.push_back(place("Paris", 3000, 5)); places.push_back(place("London", 3500, 4)); return places; } int main() { vector<place> places = get_places(); sort(places.begin(), places.end(), compare_by_rating_price_name); print(places); sort(places.begin(), places.end(), compare_by_name); print(places); } A taste of… Full text of C++98 demo
  • 28. 28 #include <iostream> #include <string> #include <algorithm> #include <vector> #include <tuple> #include <fmt/format.h> #include <fmt/ostream.h> using namespace std; struct place { string name_; long price_; int rating_; }; ostream & operator<<(ostream & to, const place & p) { fmt::print(to, "{:<20}[{}]{:7}", p.name_, p.rating_, p.price_); return to; } void print(auto & places) { for(const auto & p : places) cout << p << endl; cout << endl; } bool compare_by_rating_price_name(const place & a, const place & b) { return tie(a.rating_, a.price_, a.name_) < tie(b.rating_, b.price_, b.name_); } bool compare_by_name(const place & a, const place & b) { return a.name_ < b.name_; } vector<place> get_places() { return { {"Moscow", 1500, 3}, {"St. Petersburg", 1300, 5}, {"Minsk", 500, 4}, {"Tokyo", 3500, 4}, {"Sydney", 5000, 3}, {"Paris", 3000, 5}, {"London", 3500, 4} }; } int main() { auto places = get_places(); sort(begin(places), end(places), compare_by_rating_price_name); print(places); sort(begin(places), end(places), compare_by_name); print(places); } A taste of… Full text of C++17 demo
  • 29. 29 Why C++ became popular? Why C++ lost its popularity?
  • 30. 30 A very weak computers. Fight for efficiency is the fight for a life. Personal Computer was not a toy anymore. It was a new market. But PCs were yet more weak: "640K ought to be enough for anybody" OOP was regarded as a "silver bullet" for a software development crisis. There was a necessity of a complex tool for solving complex problems. Because almost every problem was a complex one. C++ was a such tool. Where was IT-industry at mid of 1980s?
  • 31. 31 Almost everywhere: – system software; – middleware; – server-side; – desktop (especially on Windows with OLE/COM/DCOM); – embedded; – high-performance computing; – ... With obvious exceptions in areas where tools like dBase, FoxBase, Clarion, VisualBasic were in active use. Where C++ was used before 2000s?
  • 32. 32 Computers become much more powerful. – Java is not slow now (or it is believed that Java is not slow); – Microsoft created .NET and C#. Development for Windows is now .NET-centric; – many application are developed in Python, Ruby, Erlang and so on. Internet and WWW are not toys anymore. They are a new market. – Web-development is a new niche; – migration from desktop to Web has started... IT-landscape changed at the end of 90s
  • 33. 33 Started at the beginning of 2000s. Many developers switched to more safe and powerful languages and platforms like JVM (Java, Scala), .NET (C#, F#), Python, Ruby, Erlang and so on... New projects didn't use C++. Migration of some old projects to other languages started. Visual Studio as an example. New big platforms: Apple iOS (Objective-C) and Google's Android (Java). Hype around Erlang, OCaml, Haskell and similar languages. The oblivion of C++
  • 34. 34 Why C++ is a Monster?
  • 35. 35 There are objective and subjective reasons. It is hard to speak about subjective reasons seriously: – too many features, a developer must think (think?!!!); – it is not Java nor C# nor SmallTalk nor ... – the OOP is C++ is totally wrong (so speak Alan Key); – no Garbage Collector. But there are some objective reasons which make life of a programmer harder... C++ became a monster long time ago
  • 36. 36 C++98 is almost 800 pages. C++11 is about 1400 pages. C++17 is about 1700 pages. Must read books for a C++ developer (only some of them): "The C++ Programming Language" (Bjarne Stroustrup), "C++ Standard Library Tutorial and Reference" (Nicolai Josuttis), "C++ Templates: The Complete Guide" (David Vandevoorde and Nicolai M. Josuttis), "C++ Coding Standards" (Herb Sutter and Andrei Alexandrescu), "Effective Modern C++" (Scott Meyers) and the previous books from the same author: "Effective C++", "Effective STL", "More Effective C++". See more here: The Definitive C++ Book Guide and List. C++ is a complex language
  • 37. 37 Classical example: int values[4]; values[4] = 0; It is easy to shoot to a leg
  • 38. 38 There are many ways to corrupt memory of a program: – dereference of an invalid pointer; – out of bound writes; – violation of type rules (an attempt to cast int* to double*); – use of uninitialized value; – double free of memory; – ... A program with corrupted memory may crash. Or it may not crash (it much worse). Even if it crashes there is no beautiful stack trace or something similar. A program may crash or may not...
  • 39. 39 There are plenty of UB in the language: – signed overflow; – access out of bounds; – uninitialized scalar; – null pointer dereference; – access to pointer passed to realloc; – infinite loop without side-effects; – oversized shift; – violation of type rules; – modification of the same scalar more than once in an expression; – ... Undefined behavior
  • 40. 40 #include <cstdlib> typedef int (*Function)(); static Function Do; static int EraseAll() { return system("rm -rf /"); } void NeverCalled() { Do = EraseAll; } int main() { return Do(); } Undefined behavior (`rm -rf /`)
  • 41. 41 #include <cstdlib> typedef int (*Function)(); static Function Do; static int EraseAll() { return system("rm -rf /"); } void NeverCalled() { Do = EraseAll; } int main() { return Do(); } Undefined behavior (`rm -rf /`)
  • 42. 42 NeverCalled(): # @NeverCalled() retq main: # @main movl $.L.str, %edi jmp system # TAILCALL .L.str: .asciz "rm -rf /" clang-5.0.0 -Os -std=C++11 https://godbolt.org/g/o4HxtU Undefined behavior (`rm -rf /`)
  • 43. 43 sort(begin(places), end(places), [](const auto & a, const auto & b) { const auto t = [](const auto & p) { return tie(p.rating_, p.price_, p.name_); }; return t(a) < tie(b); }); Hard to read error messages
  • 44. 44 Hard to read error messages In file included from t1_cpp14_2.cpp:5:0: C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/tuple: In instantiation of 'constexpr bool std::operator<(const std::tuple<_Tps ...>&, const std::tuple<_Elements ...>&) [with _TElements = {const int&, const long int&, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&}; _UElements = {const place&}]': t1_cpp14_2.cpp:40:16: required from 'main()::<lambda(const auto:1&, const auto:2&)> [with auto:1 = place; auto:2 = place]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/predefined_ops.h:143:18: required from 'constexpr bool __gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Iterator2 = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = main()::<lambda(const auto:1&, const auto:2&)>]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:81:17: required from 'void std::__move_median_to_first(_Iterator, _Iterator, _Iterator, _Iterator, _Compare) [with _Iterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1921:34: required from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1953:38: required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Size = long long int; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1968:25: required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:4868:18: required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = main()::<lambda(const auto:1&, const auto:2&)>]' t1_cpp14_2.cpp:41:4: required from here C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/tuple:1413:7: error: static assertion failed: tuple objects can only be compared if they have equal sizes. static_assert(sizeof...(_TElements) == sizeof...(_UElements), ^~~~~~~~~~~~~ sort(begin(places), end(places), [](const auto & a, const auto & b) { const auto t = [](const auto & p) { return tie(p.rating_, p.price_, p.name_); }; return t(a) < tie(b); });
  • 45. 45 sort(begin(places), end(places), [](const auto & a, const auto & b) { const auto t = [](const auto & p) { return tie(p.rating_, p.price_, p.name_); }; return t(a) < tie(b); }); Hard to read error messages In file included from t1_cpp14_2.cpp:5:0: C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/tuple: In instantiation of 'constexpr bool std::operator<(const std::tuple<_Tps ...>&, const std::tuple<_Elements ...>&) [with _TElements = {const int&, const long int&, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&}; _UElements = {const place&}]': t1_cpp14_2.cpp:40:16: required from 'main()::<lambda(const auto:1&, const auto:2&)> [with auto:1 = place; auto:2 = place]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/predefined_ops.h:143:18: required from 'constexpr bool __gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Iterator2 = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = main()::<lambda(const auto:1&, const auto:2&)>]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:81:17: required from 'void std::__move_median_to_first(_Iterator, _Iterator, _Iterator, _Iterator, _Compare) [with _Iterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1921:34: required from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1953:38: required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Size = long long int; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:1968:25: required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const auto:1&, const auto:2&)> >]' C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/stl_algo.h:4868:18: required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<place*, std::vector<place> >; _Compare = main()::<lambda(const auto:1&, const auto:2&)>]' t1_cpp14_2.cpp:41:4: required from here C:/mingw64-posix-7.2.0/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/tuple:1413:7: error: static assertion failed: tuple objects can only be compared if they have equal sizes. static_assert(sizeof...(_TElements) == sizeof...(_UElements), ^~~~~~~~~~~~~ 841 lines
  • 46. 46 No standard dependency manager and central dependency repository. There is some activity last years: buckaroo, build2, cget, conan, conda, cpm, cppan, hunter, vcpkg, ... But there is no a clear winner yet. No standard build tool. There are lot of tools in use: bazel, build2, buckaroo, cmake, make, meson, scons, waf, ... But there is no de-jure standard. It seems that CMake becomes a de-facto standard. Infrastructure from a 1980s
  • 47. 47 Addition of STL into C++98 made life of developers easier. Extension of stdlib in C++11 made life yet more easier. Another extension of stdlib in C++17 will made life yet more easier... But C++'s stdlib still looks very poor with comparison with other popular languages like Java, C#, Python, Ruby and so on. Shine and poverty of C++ stdlib
  • 48. 48 Many developers just don't know how to use C++ safely and efficiently. Mantra "learn C first and only then C++" is terribly wrong! C++ as a first language? May be not a good idea. Plain old C as a first language? It's much worse! People's factor
  • 50. 50 Procedural Programming Object-Oriented Programming (incl. multiple inheritance) one of the most comprehensive between statically typed OO-languages. Only Eiffel has more advanced support for OOP. Generic Programming (function and class templates and all that stuff...) compile-time duck-typing and static polymorphism. Functional Programming All these paradigms can be easily combined in a single program. C++ is a multiparadigm language
  • 51. 51 + low resources consumption + total control + an easy access to OS and hardware. Lot of resources were invested in optimizing C++ compiler and tools. There are a very few alternatives with comparable expressiveness and execution speed (if any). High performance...
  • 52. 52 You can add your own "thing" and this "thing" will behave just a language's first-class citizen. An ability to create int_set attracted me 25 years ago... Powerful and cheap abstraction
  • 53. 53 class int_set { int * items_; ... public: int_set() : items_(new int[initial_capacity]) {...} ~int_set() { delete[] items_; } ... }; int_set operator+(const int_set & a, const int_set & b) {...} int_set operator-(const int_set & a, const int_set & b) {...} int_set operator&(const int_set & a, const int_set & b) {...} int_set received_items; int_set checked_items; ... int_set delayed_items = received_items - checked_items; Powerful and cheap abstraction (int_set)
  • 54. 54 Class matrix is another classical example. Allows to write a compact and readable code: const unsigned N = ...; matrix a(N,N), b(N,N), c(N,N), d(N,N); ... matrix x = a*b + c*d; Powerful and cheap abstraction (matrix)
  • 55. 55 Class matrix is another classical example. Allows to write a compact and readable code: const unsigned N = ...; matrix a(N,N), b(N,N), c(N,N), d(N,N); ... matrix x = a*b + c*d; Powerful and cheap abstraction (matrix) A plain C alternative: matrix a, b, c, d; matrix ab, cd, x; matrix_init(&a, N, N); matrix_init(&b, N, N); matrix_init(&c, N, N); matrix_init(&d, N, N); ... matrix_init(&ab, N, N); matrix_init(&cd, N, N); matrix_init(&x); matrix_mul(&a, &b, &ab); matrix_mul(&c, &d, &cd); matrix_add(&ab, &cd, &x); matrix_destroy(&ab); matrix_destroy(&cd); ... matrix_destroy(&x); matrix_destroy(&d); matrix_destroy(&c); matrix_destroy(&b); matrix_destroy(&a);
  • 56. 56 Get a resource in the constructor. allocate memory, acquire mutex, open file, create painting device, ... Release the resource in the destructor. destructor is called automatically when object is out of scope or destroyed manually. We have already seen this in int_set example: class int_set { int * items_; ... public: int_set() : items_(new int[initial_capacity]) {...} ~int_set() { delete[] items_; } RAII (Resource Acquisition Is Initialization)
  • 57. 57 RAII is used for different types of resources, not only memory: void raii_example() { ifstream file{"input.dat", ios::binary}; if(file.is_open()) { vector<uint8_t> content = load_data(file); ... lock_guard<mutex> lock{global_data_lock}; global_data = move(content); global_data_updated.notify(); } } RAII (Resource Acquisition Is Initialization)
  • 58. 58 RAII is used for different types of resources, not only memory: void raii_example() { ifstream file{"input.dat", ios::binary}; if(file.is_open()) { vector<uint8_t> content = load_data(file); ... lock_guard<mutex> lock{global_data_lock}; global_data = move(content); global_data_updated.notify(); } } RAII (Resource Acquisition Is Initialization)
  • 59. 59 C++ is great for creation of high-level domain specific tools. High-level domain-specific tools
  • 60. 60 class User { public: ... static User fromJSON(const rapidjson::Value& doc) { if(!doc.IsObject()) throw std::runtime_error("document should be an object"); static const char* members[] = { "id", "name", "phone", "birthday" }; for(size_t i = 0; i < sizeof(members)/sizeof(members[0]); i++) if(!doc.HasMember(members[i])) throw std::runtime_error("missing fields"); uint64_t id = doc["id"].GetUint64(); std::string name = doc["name"].GetString(); uint64_t phone = doc["phone"].GetUint64(); Date birthday = Date::fromJSON(doc["birthday"]); User result(id, name, phone, birthday); return result; } }; Domain specific tools (JSON example) RapidJSON
  • 61. 61 class User { public: ... template<typename Json_Io> void json_io(Json_Io & io) { io & json_dto::mandatory("id", _id) & json_dto::mandatory("name", _name) & json_dto::mandatory("birthday", _birthday) & json_dto::mandatory("phone", _phone); } }; Domain specific tools (JSON example) RapidJSON + json_dto
  • 62. 62 How to use C++ safely and efficiently?
  • 63. 63 Use only that you know. Any safe subset of C++ is still C++. Common sense rulezzz!
  • 64. 64 There are a lot of for different application areas: – C++ Core Guidelines; – guidelines from famous companies or projects (Google's, Boost's, Mozilla's, Bloomberg's, CERT's, ...); – industry-specific standard and/or guidelines (Joint Strike Fighter Air Vehicle C++ Coding Standards, MISRA C++, High Integrity C++,...) Use guidelines
  • 65. 65 Static code analyzers: – cppcheck; – clang static analyzer; – Coverity; – PVS-Studio. Sanitizers (GCC, clang): – address; – thread; – leak; – undefined. Compiler flags like -Wall, -Weverything and -Werror are your friends! Use analyzers and sanitizers
  • 66. 66 /// Open a device and get handle for it. /// /// attention A dynamically allocated object returned. Caller must deallocate it. device * open_device( /// Name of device to be created. const char * dev_name, /// Creation options. device_options options); ... auto dev = open_device("lpt1", defaults); dev->write(...); ... delete dev; Use right abstractions (1)
  • 67. 67 /// Open a device and get handle for it. unique_ptr<device> open_device( /// Name of device to be created. const char * dev_name, /// Creation options. device_options options); ... auto dev = open_device("lpt1", defaults); dev->write(...); ... Use right abstractions (2)
  • 68. 68 Many developers abandon type-safe API if it requires a lot of boilerplate code: ostream & operator<<(ostream & o, const place & p) { o << setw(20) << left << p.name_ << "[" << p.rating_ << "]" << setw(7) << right << p.price_; return o; } Use right libraries (type safety)
  • 69. 69 And use something more "useful" and/or "powerful": ostream & operator<<(ostream & o, const place & p) { char buf[30]; snprintf(buf, sizeof(buf), "%-20s[%d]%7d", p.name_, p.rating_, p.price_); return (o << buf); } Use right libraries (type safety)
  • 70. 70 And use something more "useful" and/or "powerful": ostream & operator<<(ostream & o, const place & p) { char buf[30]; snprintf(buf, sizeof(buf), "%-20s[%d]%7d", p.name_, p.rating_, p.price_); return (o << buf); } Use right libraries (type safety) 30 characters required for textual representation. But addition character is necessary for terminating 0-symbol. place::price_ is unsigned long, "%7ld" must be used instead of "%7d". place::name_ is std::string, not char*, place.name_.c_str() must be used.
  • 71. 71 There are powerful and type-safe libraries. fmtlib as an example: #include <fmt/format.h> #include <fmt/ostream.h> ostream & operator<<(ostream & o, const place & p) { fmt::print(o, "{:<20}[{}]{:7}", p.name_, p.rating_, p.price_); return o; } Use right libraries (type safety)
  • 72. 72 How many lines of modern C++ are necessary to write the simplest HTTP- server? A server that responds "Hello, world" for all requests? Use right libraries (simplicity)
  • 73. 73 Simplest HTTP-server in Boost.Beast: Use right libraries (simplicity) #include <boost/program_options.hpp> #include <iostream> #include <thread> #include <mutex> #include <boost/beast/http.hpp> #include <boost/beast/core/handler_ptr.hpp> #include <boost/beast/core/multi_buffer.hpp> #include <boost/beast/core/flat_buffer.hpp> #include <boost/asio.hpp> #include <app_args.hpp> using namespace boost::beast; using namespace boost::beast::http; class http_server_t { using endpoint_type = boost::asio::ip::tcp::endpoint; using address_type = boost::asio::ip::address; using socket_type = boost::asio::ip::tcp::socket; using req_type = request<string_body>; using resp_type = response<string_body>; endpoint_type ep_; boost::asio::io_service ios_; boost::asio::ip::tcp::acceptor acceptor_; socket_type sock_; public: http_server_t(endpoint_type const& ep ) : ep_(ep), acceptor_(ios_), sock_(ios_) {} void run() { acceptor_.open(ep_.protocol()); acceptor_.bind(ep_); acceptor_.listen( boost::asio::socket_base::max_connections); acceptor_.async_accept(sock_, std::bind(&http_server_t::on_accept, this, std::placeholders::_1)); boost::asio::signal_set break_signals{ ios_, SIGINT }; break_signals.async_wait( [&]( const auto & ec, int ){ if( !ec ) { error_code ec; ios_.dispatch( [&]{ acceptor_.close(ec); }); } } ); ios_.run(); } private: template<class Stream, class Handler, bool isRequest, class Body, class Fields> class write_op { struct data { bool cont; Stream& s; message<isRequest, Body, Fields> m; data(Handler& handler, Stream& s_, message<isRequest, Body, Fields>&& m_) : s(s_), m(std::move(m_)) { using boost::asio::asio_handler_is_continuation; cont = asio_handler_is_continuation(std::addressof(handler)); } }; handler_ptr<data, Handler> d_; public: write_op(write_op&&) = default; write_op(write_op const&) = default; template<class DeducedHandler, class... Args> write_op(DeducedHandler&& h, Stream& s, Args&&... args) : d_(std::forward<DeducedHandler>(h), s, std::forward<Args>(args)...) { (*this)(error_code{}, false); } void operator()(error_code ec, bool again = true) { auto& d = *d_; d.cont = d.cont || again; if(! again) { boost::beast::http::async_write(d.s, d.m, std::move(*this)); return; } d_.invoke(ec); } friend void* asio_handler_allocate(std::size_t size, write_op* op) { using boost::asio::asio_handler_allocate; return asio_handler_allocate( size, std::addressof(op->d_.handler())); } friend void asio_handler_deallocate(void* p, std::size_t size, write_op* op) { using boost::asio::asio_handler_deallocate; asio_handler_deallocate( p, size, std::addressof(op->d_.handler())); } friend bool asio_handler_is_continuation(write_op* op) { return op->d_->cont; } template<class Function> friend void asio_handler_invoke(Function&& f, write_op* op) { using boost::asio::asio_handler_invoke; asio_handler_invoke( f, std::addressof(op->d_.handler())); } }; template<class Stream, bool isRequest, class Body, class Fields, class DeducedHandler> static void async_write( Stream& stream, message<isRequest, Body, Fields>&& msg, DeducedHandler&& handler) { write_op<Stream, typename std::decay<DeducedHandler>::type, isRequest, Body, Fields>{std::forward<DeducedHandler>( handler), stream, std::move(msg)}; } class peer : public std::enable_shared_from_this<peer> { flat_buffer sb_{ 1024 }; socket_type sock_; req_type req_; public: peer(peer&&) = default; peer(peer const&) = default; peer& operator=(peer&&) = delete; peer& operator=(peer const&) = delete; peer(socket_type&& sock) : sock_(std::move(sock)) {} void run() { do_read(); } void do_read() { async_read(sock_, sb_, req_, std::bind(&peer::on_read, this->shared_from_this(), std::placeholders::_1)); } void on_read(error_code const& ec) { if(!ec) { resp_type res; res.result(status::ok); res.version( req_.version() ); res.insert(field::server, "Beast"); res.insert(field::content_type, "text/plain; charset=utf-8"); res.keep_alive( true ); res.body() = "Hello, World!"; res.prepare_payload(); async_write(sock_, std::move(res), std::bind(&peer::on_write, this->shared_from_this(), std::placeholders::_1)); } } void on_write(error_code ec) { if(!ec) do_read(); } }; void on_accept(error_code const& ec) { if(!acceptor_.is_open()) return; if(!ec) { socket_type sock(std::move(sock_)); std::make_shared<peer>(std::move(sock))->run(); } acceptor_.async_accept(sock_, std::bind(&http_server_t::on_accept, this, std::placeholders::_1)); } }; int main() { using endpoint_type = boost::asio::ip::tcp::endpoint; using address_type = boost::asio::ip::address; endpoint_type ep{address_type::from_string( "127.0.0.1" ), 8080 }; http_server_t server{ ep }; server.run(); return 0; }
  • 74. 74 Simplest HTTP-server in RESTinio: #include <restinio/all.hpp> int main() { restinio::run( restinio::on_this_thread() .port(8080) .address("localhost") .request_handler([](auto req) { return req->create_response().set_body("Hello, World!").done(); })); return 0; } Use right libraries (simplicity)
  • 75. 75 There are many different C++ libraries for different areas. Some of them: Generic: Boost, Folly, Abseil, BDE; Networking: Asio, ACE, POCO; GUI: Qt, FLTK, wxWidgets, nana; i18n: ICU; Linear algebra: Boost.uBLAS, Eigen, Blitz++; Concurrency+Parallel computing: TBB, HPX, Thrust; Lock-free: libcds; Actors: QP/C++, CAF, SObjectizer; REST: C++ REST SDK, RestBed, Pistache, RESTinio; Web: CppCMS, Tntnet, TreeFrog, Wt; JSON: RapidJSON, json; RDBMS: OTL, SOCI, sqlpp11; Testing: Boost.Test, gTest, Catch2, doctest; ... Use right libraries Useful links collections: Awesome C++ Libraries (github), Awesome C++ Libraries (libhunt), Non-ANSI/ISO C++ Libs on cppreference.com
  • 76. 76 Where C++ can be used now?
  • 77. 77 IT-landscape has changed but there are still many areas where high performance and low resource consumptions matter. Smartphones and mobile development are here. Battery life matters. High diversity of devices in use: PC, laptops/netbooks, tablets, smartphones, smart watches, smart TVs, game consoles, ... Big server farms. Free lunch is over. It's not an easy to take a performance gain now. The return of interest in native code apps. 2011-2017: what's changed?
  • 78. 78 C++ Futures on Instagram: high-performing recommendation service was rewritten in C++. number of servers reduced from 720 to 38. Speedup PHP at Facebook: HipHop (PHP-to-C++ transpiler) and HHVM (HipHop Virtual Machine). Some examples. Server-side
  • 79. 79 ScyllaDB: a high performance drop-in replacement for Cassandra. 10x better performance on high-end hardware, 1.5x-3x better on smaller machines. Quantcast File System: a high performance alternative to HDFS (Hadoop Distributed File System) written in C++. 50% space reduction, +75% write and +45% read throughput. Some examples. Middleware
  • 80. 80 Doodle Kindom: cross-plaform games with kernel in C++. works on iPhone, iPad, Windows, MacOS, NOOK. Oncam: a videochat system for iOS+Android with kernel in C++. supports videochat up to 6 participant with at least 15FPS. Some examples. Mobile
  • 81. 81 High performance computing – weather forecasting, molecular modeling, physic simulation, big-data, machine learning, ... Low resource consumption – mobile application, internet of things, ... System programming (and around) – OS kernels, drivers and utilities, middleware, compilers, antiviruses, ... Real-time and embedded systems – SCADA, industrial internet of things, avionics, automotive, finance, telecom, defense, ... Complex desktop applications – CADs, photoshop, AAA games, browsers, office apps, ... Cross-platform apps – app's kernel in C++ + GUI in native technology (Dropbox's jinie), ... Legacy Where C++ can be used now?
  • 82. 82 There is no place for quick- and-dirty solutions! What is in common?
  • 83. 83 Who is trying to eat C++ now?
  • 84. 84 Java and C#: It is not actual anymore :) Java and C# already ate everything they could. plain C: It is actual again. Suddenly? Go: Shines in its very narrow niche. Attracts much more Python/Ruby developers than C++ devs. Rust: The only real modern alternative to C++ now. But it is a hard question. Main alternatives
  • 85. 85 Ada: Very strong competitor for embedded and real-time areas. Almost unknown in East Europe. D: It's too late. Lack of popularity and presence of GC. Swift: Almost nonexistent outside the Apple's ecosystem. Some other alternatives
  • 86. 86 C++ is a community- driven language
  • 87. 87 There is no commercial force behind it (like Oracle for Java, Microsoft for C#, JetBrains for Kotlin and so on). If you need something in C++ you can propose it: https://stdcpp.ru/ C++ is community driven language