SlideShare ist ein Scribd-Unternehmen logo
1 von 71
Downloaden Sie, um offline zu lesen
Mateusz Pusz
November 15, 2017
POINTLESS POINTERS
HOW TO MAKE OUR INTERFACES EFFICIENT?
code::dive 2017 | Pointless Pointers
WHAT IS A POINTER?
2
A pointer is a programming language data type whose value refers
directly to (or "points to") another value stored elsewhere in the
computer memory using its address.
-- Wikipedia
code::dive 2017 | Pointless Pointers
WHAT IS A POINTER?
2
code::dive 2017 | Pointless Pointers
WHAT IS A POINTER?
3
Pointers due to their ambiguous nature are the source of most
problems and bugs in C++ code. Lack of understanding between
code architect and the user results in crashes, asserts and memory
leaks!!!
-- Mateusz Pusz ☺
code::dive 2017 | Pointless Pointers
WHAT IS A POINTER?
3
code::dive 2017 | Pointless Pointers
POINTERS MISUSE LEADS TO
4
code::dive 2017 | Pointless Pointers
POINTERS MISUSE LEADS TO
Null Pointer Dereference
4
code::dive 2017 | Pointless Pointers
POINTERS MISUSE LEADS TO
Null Pointer Dereference
Resource leaks
4
code::dive 2017 | Pointless Pointers
POINTERS MISUSE LEADS TO
Null Pointer Dereference
Resource leaks
Bu er Overflows
4
code::dive 2017 | Pointless Pointers
POINTERS MISUSE LEADS TO
Null Pointer Dereference
Resource leaks
Bu er Overflows
Hangs!
4
code::dive 2017 | Pointless Pointers
POINTERS MISUSE LEADS TO
Null Pointer Dereference
Resource leaks
Bu er Overflows
Hangs!
Crashes!
4
code::dive 2017 | Pointless Pointers
POINTERS MISUSE LEADS TO
Null Pointer Dereference
Resource leaks
Bu er Overflows
Hangs!
Crashes!Stability!!!
4
code::dive 2017 | Pointless Pointers
POINTERS MISUSE LEADS TO
Null Pointer Dereference
Resource leaks
Bu er Overflows
Hangs!
Crashes!Stability!!!
Security!!!
4
B* a(A* ptr) { /* ... */; return b(ptr); }
code::dive 2017 | Pointless Pointers
PROBLEM DEFINITION
5
B* a(A* ptr) { /* ... */; return b(ptr); }
B* b(A* ptr) { /* ... */; return c(ptr); }
code::dive 2017 | Pointless Pointers
PROBLEM DEFINITION
5
B* a(A* ptr) { /* ... */; return b(ptr); }
B* b(A* ptr) { /* ... */; return c(ptr); }
B* c(A* ptr) { /* ... */; return d(ptr); }
code::dive 2017 | Pointless Pointers
PROBLEM DEFINITION
5
B* a(A* ptr) { /* ... */; return b(ptr); }
B* b(A* ptr) { /* ... */; return c(ptr); }
B* c(A* ptr) { /* ... */; return d(ptr); }
B* d(A* ptr) { /* ... */; return e(ptr); }
code::dive 2017 | Pointless Pointers
PROBLEM DEFINITION
5
B* a(A* ptr) { /* ... */; return b(ptr); }
B* b(A* ptr) { /* ... */; return c(ptr); }
B* c(A* ptr) { /* ... */; return d(ptr); }
B* d(A* ptr) { /* ... */; return e(ptr); }
B* e(A* ptr) { /* ... */; return f(ptr); }
code::dive 2017 | Pointless Pointers
PROBLEM DEFINITION
5
B* a(A* ptr) { /* ... */; return b(ptr); }
B* b(A* ptr) { /* ... */; return c(ptr); }
B* c(A* ptr) { /* ... */; return d(ptr); }
B* d(A* ptr) { /* ... */; return e(ptr); }
B* e(A* ptr) { /* ... */; return f(ptr); }
B* f(A* ptr) { /* ... */; return g(ptr); }
code::dive 2017 | Pointless Pointers
PROBLEM DEFINITION
5
B* a(A* ptr) { /* ... */; return b(ptr); }
B* b(A* ptr) { /* ... */; return c(ptr); }
B* c(A* ptr) { /* ... */; return d(ptr); }
B* d(A* ptr) { /* ... */; return e(ptr); }
B* e(A* ptr) { /* ... */; return f(ptr); }
B* f(A* ptr) { /* ... */; return g(ptr); }
B* g(A* ptr) { /* ... */; return *ptr; }
code::dive 2017 | Pointless Pointers
PROBLEM DEFINITION
5
B* a(A* ptr) { /* ... */; assert(ptr); return b(ptr); }
B* b(A* ptr) { /* ... */; assert(ptr); return c(ptr); }
B* c(A* ptr) { /* ... */; assert(ptr); return d(ptr); }
B* d(A* ptr) { /* ... */; assert(ptr); return e(ptr); }
B* e(A* ptr) { /* ... */; assert(ptr); return f(ptr); }
B* f(A* ptr) { /* ... */; assert(ptr); return g(ptr); }
B* g(A* ptr) { /* ... */; assert(ptr); return *ptr; }
code::dive 2017 | Pointless Pointers
PROBLEM DEFINITION
6
B* a(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return b(ptr); }
B* b(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return c(ptr); }
B* c(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return d(ptr); }
B* d(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return e(ptr); }
B* e(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return f(ptr); }
B* f(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return g(ptr); }
B* g(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return *ptr; }
code::dive 2017 | Pointless Pointers
PROBLEM DEFINITION
7
B* func(A* arg);
code::dive 2017 | Pointless Pointers
QUIZ - GUESS WHAT?
8
person* add(name* n);
code::dive 2017 | Pointless Pointers
QUIZ - GUESS WHAT?
9
person* add(name* n);
code::dive 2017 | Pointless Pointers
QUIZ - GUESS WHAT?
Is it better now?
Is it enough?
Do you know how to use that function?
Do you know how to implement that function?
9
person* add(name* n);
void foo()
{
person* p = add(new name{"Mateusz Pusz"});
assert(p != nullptr);
process(p->id(), p->name());
delete p;
}
code::dive 2017 | Pointless Pointers
ADD() USAGE – TAKE #1
10
person* add(name* n);
void foo()
{
person* p = add(new name{"Mateusz Pusz"});
assert(p != nullptr);
process(p->id(), p->name());
delete p;
}
code::dive 2017 | Pointless Pointers
ADD() USAGE – TAKE #1
Is that a valid usage of add() interface?
What are potential problems with above code?
10
person* add(name* n);
void foo()
{
name n{"Mateusz Pusz"};
person* p = add(&n);
if(p != nullptr)
process(p->id(), p->name());
}
code::dive 2017 | Pointless Pointers
ADD() USAGE – TAKE #2
11
person* add(name* n);
void foo()
{
name n{"Mateusz Pusz"};
person* p = add(&n);
if(p != nullptr)
process(p->id(), p->name());
}
code::dive 2017 | Pointless Pointers
ADD() USAGE – TAKE #2
Is that a valid usage of add() interface?
11
person* add(name* n);
void foo()
{
name* n = new name{"Mateusz Pusz"};
person* p = add(n);
if(p != nullptr)
process(p->id(), p->name());
delete n;
}
code::dive 2017 | Pointless Pointers
ADD() USAGE – TAKE #3
12
person* add(name* n);
void foo()
{
name* n = new name{"Mateusz Pusz"};
person* p = add(n);
if(p != nullptr)
process(p->id(), p->name());
delete n;
}
code::dive 2017 | Pointless Pointers
ADD() USAGE – TAKE #3
Is that a valid usage of add() interface?
What are potential problems with above code?
12
person* add(name* n);
void foo()
{
name names[] = {"Mateusz Pusz", "Jan Kowalski", ""};
person* people = add(names);
assert(people != nullptr);
for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i)
process(people[i].id(), people[i].name());
delete[] people;
}
code::dive 2017 | Pointless Pointers
ADD() USAGE – TAKE #4
13
person* add(name* n);
void foo()
{
name names[] = {"Mateusz Pusz", "Jan Kowalski", ""};
person* people = add(names);
assert(people != nullptr);
for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i)
process(people[i].id(), people[i].name());
delete[] people;
}
code::dive 2017 | Pointless Pointers
ADD() USAGE – TAKE #4
Is that a valid usage of add() interface?
What are potential problems with above code?
13
void foo()
{
person* p = add(new name{"Mateusz Pusz"});
assert(p != nullptr);
process(p->id(), p->name());
delete p;
}
void foo()
{
name n{"Mateusz Pusz"};
person* p = add(&n);
if(p != nullptr)
process(p->id(), p->name());
}
void foo()
{
name* n = new name{"Mateusz Pusz"};
person* p = add(n);
if(p != nullptr)
process(p->id(), p->name());
delete n;
}
void foo()
{
name names[] = {"Mateusz Pusz", "Jan Kowalski", ""};
person* people = add(names);
assert(people != nullptr);
for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i)
process(people[i].id(), people[i].name());
delete[] people;
}
code::dive 2017 | Pointless Pointers
1
2
3
4
WHICH ONE IS CORRECT?
14
void foo()
{
person* p = add(new name{"Mateusz Pusz"});
assert(p != nullptr);
process(p->id(), p->name());
delete p;
}
void foo()
{
name n{"Mateusz Pusz"};
person* p = add(&n);
if(p != nullptr)
process(p->id(), p->name());
}
void foo()
{
name* n = new name{"Mateusz Pusz"};
person* p = add(n);
if(p != nullptr)
process(p->id(), p->name());
delete n;
}
void foo()
{
name names[] = {"Mateusz Pusz", "Jan Kowalski", ""};
person* people = add(names);
assert(people != nullptr);
for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i)
process(people[i].id(), people[i].name());
delete[] people;
}
code::dive 2017 | Pointless Pointers
1
2
3
4
QUIZ - MATCH IMPLEMENTATION
std::deque<person> people;
person* add(name* n)
{
people.emplace_back((n != nullptr) ? *n : "anonymous");
return &people.back();
}
15
void foo()
{
person* p = add(new name{"Mateusz Pusz"});
assert(p != nullptr);
process(p->id(), p->name());
delete p;
}
void foo()
{
name* n = new name{"Mateusz Pusz"};
person* p = add(n);
if(p != nullptr)
process(p->id(), p->name());
delete n;
}
void foo()
{
name names[] = {"Mateusz Pusz", "Jan Kowalski", ""};
person* people = add(names);
assert(people != nullptr);
for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i)
process(people[i].id(), people[i].name());
delete[] people;
}
code::dive 2017 | Pointless Pointers
QUIZ - MATCH IMPLEMENTATION
1
void foo()
{
name n{"Mateusz Pusz"};
person* p = add(&n);
if(p != nullptr)
process(p->id(), p->name());
}
2
3
4
person* add(name* n)
{
assert(n);
int num = 0;
for(auto ptr = n; *ptr != ""; ++ptr)
++num;
person* p = new person[num];
for(auto i = 0; i<num; ++i)
p[i].name(n[i]);
return p;
}
16
void foo()
{
person* p = add(new name{"Mateusz Pusz"});
assert(p != nullptr);
process(p->id(), p->name());
delete p;
}
void foo()
{
name* n = new name{"Mateusz Pusz"};
person* p = add(n);
if(p != nullptr)
process(p->id(), p->name());
delete n;
}
code::dive 2017 | Pointless Pointers
QUIZ - MATCH IMPLEMENTATION
1
void foo()
{
name n{"Mateusz Pusz"};
person* p = add(&n);
if(p != nullptr)
process(p->id(), p->name());
}
2
3
void foo()
{
name names[] = {"Mateusz Pusz", "Jan Kowalski", ""};
person* people = add(names);
assert(people != nullptr);
for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i)
process(people[i].id(), people[i].name());
delete[] people;
}
4
person* add(name* n)
{
assert(n != nullptr);
return new person{n};
}
17
void foo()
{
name* n = new name{"Mateusz Pusz"};
person* p = add(n);
if(p != nullptr)
process(p->id(), p->name());
delete n;
}
code::dive 2017 | Pointless Pointers
QUIZ - MATCH IMPLEMENTATION
void foo()
{
person* p = add(new name{"Mateusz Pusz"});
assert(p != nullptr);
process(p->id(), p->name());
delete p;
}
void foo()
{
name n{"Mateusz Pusz"};
person* p = add(&n);
if(p != nullptr)
process(p->id(), p->name());
}
1
2
3
void foo()
{
name names[] = {"Mateusz Pusz", "Jan Kowalski", ""};
person* people = add(names);
assert(people != nullptr);
for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i)
process(people[i].id(), people[i].name());
delete[] people;
}
4
std::deque<person> people;
person* add(name* n)
{
if(n == nullptr)
return nullptr;
auto it = find_if(begin(people), end(people),
[&](person& p)
{ return p.name() == *n; });
if(it != end(people))
return nullptr;
people.emplace_back(*n);
return &people.back();
}
18
code::dive 2017 | Pointless Pointers
QUIZ - MATCH IMPLEMENTATION
void foo()
{
person* p = add(new name{"Mateusz Pusz"});
assert(p != nullptr);
process(p->id(), p->name());
delete p;
}
void foo()
{
name n{"Mateusz Pusz"};
person* p = add(&n);
if(p != nullptr)
process(p->id(), p->name());
}
void foo()
{
name* n = new name{"Mateusz Pusz"};
person* p = add(n);
if(p != nullptr)
process(p->id(), p->name());
delete n;
}
void foo()
{
name names[] = {"Mateusz Pusz", "Jan Kowalski", ""};
person* people = add(names);
assert(people != nullptr);
for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i)
process(people[i].id(), people[i].name());
delete[] people;
}
1
2
3
4
19
person*
add(name* n);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
20
person*
add(name* n);
std::unique_ptr<person>
add(std::unique_ptr<name> n);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
20
person*
add(name* n);
std::unique_ptr<person>
add(std::unique_ptr<name> n);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
Do you know how to use that function?
Do you know how to implement that function?
20
person*
add(name* n)
{
assert(n != nullptr);
return new person{n};
}
void foo()
{
person* p = add(
new name{"Mateusz Pusz"});
assert(p != nullptr);
process(p->id(), p->name());
delete p;
}
code::dive 2017 | Pointless Pointers
USING C++ THE RIGHT WAY – CASE #1
21
void foo()
{
auto p = add(
std::make_unique<name>("Mateusz Pusz"));
assert(p != nullptr);
process(p->id(), p->name());
}
std::unique_ptr<person>
add(std::unique_ptr<name> n)
{
assert(n != nullptr);
return std::make_unique<person>(std::move(n));
}
code::dive 2017 | Pointless Pointers
USING C++ THE RIGHT WAY – CASE #1
person*
add(name* n)
{
assert(n != nullptr);
return new person{n};
}
void foo()
{
person* p = add(
new name{"Mateusz Pusz"});
assert(p != nullptr);
process(p->id(), p->name());
delete p;
}
21
person*
add(name* n);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
22
person*
add(name* n);
person&
add(std::optional<name> n);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
22
person*
add(name* n);
person&
add(std::optional<name> n);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
Do you know how to use that function?
Do you know how to implement that function?
22
std::deque<person> people;
person* add(name* n)
{
people.emplace_back(
(n != nullptr) ? *n : "anonymous");
return &people.back();
}
void foo()
{
name n{"Mateusz Pusz"};
person* p = add(&n);
if(p != nullptr)
process(p->id(), p->name());
}
code::dive 2017 | Pointless Pointers
USING C++ THE RIGHT WAY – CASE #2
23
std::deque<person> people;
person& add(std::optional<name> n)
{
people.emplace_back(
n ? std::move(*n) : "anonymous");
return people.back();
}
void foo()
{
person& p = add(name{"Mateusz Pusz"});
process(p.id(), p.name());
}
code::dive 2017 | Pointless Pointers
USING C++ THE RIGHT WAY – CASE #2
std::deque<person> people;
person* add(name* n)
{
people.emplace_back(
(n != nullptr) ? *n : "anonymous");
return &people.back();
}
void foo()
{
name n{"Mateusz Pusz"};
person* p = add(&n);
if(p != nullptr)
process(p->id(), p->name());
}
23
person*
add(name* n);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
24
person*
add(name* n);
std::tuple<person&, bool>
add(name n);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
24
person*
add(name* n);
std::tuple<person&, bool>
add(name n);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
Do you know how to use that function?
Do you know how to implement that function?
24
std::deque<person> people;
person* add(name* n)
{
if(n == nullptr) return nullptr;
auto it = find_if(
begin(people), end(people),
[&](person& p) { return p.name() == *n; });
if(it != end(people))
return nullptr;
people.emplace_back(*n);
return &people.back();
}
void foo()
{
name* n = new name{"Mateusz Pusz"};
person* p = add(n);
if(p != nullptr)
process(p->id(), p->name());
delete n;
}
code::dive 2017 | Pointless Pointers
USING C++ THE RIGHT WAY – CASE #3
25
std::deque<person> people;
std::tuple<person&, bool> add(name n)
{
auto it = find_if(
begin(people), end(people),
[&](person& p) { return p.name() == n; });
if(it != end(people))
return { *it, false };
people.emplace_back(std::move(n));
return { people.back(), true };
}
void foo()
{
auto r = add(name{"Mateusz Pusz"});
if(std::get<bool>(r))
process(std::get<0>(r).id(), std::get<0>(r).name());
}
code::dive 2017 | Pointless Pointers
USING C++ THE RIGHT WAY – CASE #3
std::deque<person> people;
person* add(name* n)
{
if(n == nullptr) return nullptr;
auto it = find_if(
begin(people), end(people),
[&](person& p) { return p.name() == *n; });
if(it != end(people))
return nullptr;
people.emplace_back(*n);
return &people.back();
}
void foo()
{
name* n = new name{"Mateusz Pusz"};
person* p = add(n);
if(p != nullptr)
process(p->id(), p->name());
delete n;
}
25
person*
add(name* n);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
26
person*
add(name* n);
std::vector<person>
add(std::vector<name> names);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
26
person*
add(name* n);
std::vector<person>
add(std::vector<name> names);
code::dive 2017 | Pointless Pointers
IS THERE A BETTER SOLUTION?
Do you know how to use that function?
Do you know how to implement that function?
26
person* add(name* n)
{
assert(n);
int num = 0;
for(auto ptr = n; *ptr != ""; ++ptr)
++num;
person* p = new person[num];
for(auto i = 0; i<num; ++i)
p[i].name(n[i]);
return p;
}
void foo()
{
name names[] = {"Mateusz Pusz", "Jan Kowalski", ""};
person* people = add(names);
assert(people != nullptr);
for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i)
process(people[i].id(), people[i].name());
delete[] people;
}
code::dive 2017 | Pointless Pointers
USING C++ THE RIGHT WAY – CASE #4
27
std::vector<person> add(std::vector<name> names)
{
std::vector<person> p;
p.reserve(names.size());
for(auto& n : names)
p.emplace_back(std::move(n));
return p;
}
void foo()
{
auto people = add({"Mateusz Pusz", "Jan Kowalski"});
for(auto& p : people)
process(p.id(), p.name());
}
code::dive 2017 | Pointless Pointers
USING C++ THE RIGHT WAY – CASE #4
person* add(name* n)
{
assert(n);
int num = 0;
for(auto ptr = n; *ptr != ""; ++ptr)
++num;
person* p = new person[num];
for(auto i = 0; i<num; ++i)
p[i].name(n[i]);
return p;
}
void foo()
{
name names[] = {"Mateusz Pusz", "Jan Kowalski", ""};
person* people = add(names);
assert(people != nullptr);
for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i)
process(people[i].id(), people[i].name());
delete[] people;
}
27
ARGUMENT TYPE POINTER ARGUMENT DECLARATION
Mandatory big value void foo(A* in);
Output function argument void foo(A* out);
Array void foo(A* array);
Optional value void foo(A* opt);
Ownership passing void foo(A* ptr);
code::dive 2017 | Pointless Pointers
POINTERS USAGE IN ANSI C
29
ARGUMENT TYPE POINTER ARGUMENT DECLARATION
Mandatory big value void foo(A* in);
Output function argument void foo(A* out);
Array void foo(A* array);
Optional value void foo(A* opt);
Ownership passing void foo(A* ptr);
code::dive 2017 | Pointless Pointers
POINTERS USAGE IN ANSI C
Pointer ambiguity makes it really hard to understand the intent of the
interface author.
29
ARGUMENT TYPE POINTER ARGUMENT DECLARATION
Mandatory big value void foo(const A& in);
Output function argument A foo(); or std::tuple<...> foo(); or void foo(A& out);
Array void foo(const std::vector<A>& a);
Optional value void foo(std::optional<A> opt); or void foo(A* opt);
Ownership passing void foo(std::unique_ptr<A> ptr);
code::dive 2017 | Pointless Pointers
DOING IT C++ WAY
30
ARGUMENT TYPE POINTER ARGUMENT DECLARATION
Mandatory big value void foo(const A& in);
Output function argument A foo(); or std::tuple<...> foo(); or void foo(A& out);
Array void foo(const std::vector<A>& a);
Optional value void foo(std::optional<A> opt); or void foo(A* opt);
Ownership passing void foo(std::unique_ptr<A> ptr);
code::dive 2017 | Pointless Pointers
DOING IT C++ WAY
Use above Modern C++ constructs to explicitly state your design intent.
30
B foo(std::optional<A> arg);
const A& foo(const std::array<A, 3>& arg);
std::unique_ptr<B> foo(A arg);
std::vector<B> foo(const A& arg);
code::dive 2017 | Pointless Pointers
QUIZ – GUESS WHAT?
31
int count_lower(const char* ptr, size_t size);
void add_2(int* ptr, size_t size);
code::dive 2017 | Pointless Pointers
C++17 AND C++20: WHAT ABOUT POINTER AND A SIZE
ANSI C -> C++14
ANSI C -> C++14
32
int count_lower(const char* ptr, size_t size);
void add_2(int* ptr, size_t size);
int count_lower(std::string_view txt);
void add_2(std::span<int> array);
code::dive 2017 | Pointless Pointers
C++17 AND C++20: WHAT ABOUT POINTER AND A SIZE
ANSI C -> C++14
ANSI C -> C++14
C++17
C++20
32
TAKEAWAYS
C++ is a powerful tool:
• strong type system
• better abstractions
• templates
• C++ STD library
code::dive 2017 | Pointless Pointers
C++ IS NOT ANSI C!!!
34
Pointless Pointers - How to make our interfaces efficient?
Pointless Pointers - How to make our interfaces efficient?

Weitere ähnliche Inhalte

Was ist angesagt?

Dns server clients (actual program)
Dns server clients (actual program)Dns server clients (actual program)
Dns server clients (actual program)
Youssef Dirani
 
Network lab manual
Network lab manualNetwork lab manual
Network lab manual
Prabhu D
 
Network lap pgms 7th semester
Network lap pgms 7th semesterNetwork lap pgms 7th semester
Network lap pgms 7th semester
DOSONKA Group
 
c++ program for Railway reservation
c++ program for Railway reservationc++ program for Railway reservation
c++ program for Railway reservation
Swarup Kumar Boro
 

Was ist angesagt? (19)

The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our Ways
 
Dns server clients (actual program)
Dns server clients (actual program)Dns server clients (actual program)
Dns server clients (actual program)
 
Network lab manual
Network lab manualNetwork lab manual
Network lab manual
 
Effective Object Oriented Design in Cpp
Effective Object Oriented Design in CppEffective Object Oriented Design in Cpp
Effective Object Oriented Design in Cpp
 
Lecture2
Lecture2Lecture2
Lecture2
 
Network lap pgms 7th semester
Network lap pgms 7th semesterNetwork lap pgms 7th semester
Network lap pgms 7th semester
 
Defcon 23 - Daniel Selifonov - drinking from LETHE
Defcon 23 - Daniel Selifonov - drinking from LETHEDefcon 23 - Daniel Selifonov - drinking from LETHE
Defcon 23 - Daniel Selifonov - drinking from LETHE
 
Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?
 
Algorithm
AlgorithmAlgorithm
Algorithm
 
Enrichment lecture EE Technion (parts A&B) also including the subject of VHDL...
Enrichment lecture EE Technion (parts A&B) also including the subject of VHDL...Enrichment lecture EE Technion (parts A&B) also including the subject of VHDL...
Enrichment lecture EE Technion (parts A&B) also including the subject of VHDL...
 
Write Your Own Compiler in 24 Hours
Write Your Own Compiler in 24 HoursWrite Your Own Compiler in 24 Hours
Write Your Own Compiler in 24 Hours
 
How to Parse a File (DDD North 2017)
How to Parse a File (DDD North 2017)How to Parse a File (DDD North 2017)
How to Parse a File (DDD North 2017)
 
Computer science project work
Computer science project workComputer science project work
Computer science project work
 
rubik_solve
rubik_solverubik_solve
rubik_solve
 
Mixing C++ & Python II: Pybind11
Mixing C++ & Python II: Pybind11Mixing C++ & Python II: Pybind11
Mixing C++ & Python II: Pybind11
 
Good Code
Good CodeGood Code
Good Code
 
Computer Networks Lab File
Computer Networks Lab FileComputer Networks Lab File
Computer Networks Lab File
 
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
 
c++ program for Railway reservation
c++ program for Railway reservationc++ program for Railway reservation
c++ program for Railway reservation
 

Ähnlich wie Pointless Pointers - How to make our interfaces efficient?

C++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorC++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operator
Jussi Pohjolainen
 
using set identitiesSolutionimport java.util.Scanner; c.pdf
using set identitiesSolutionimport java.util.Scanner;  c.pdfusing set identitiesSolutionimport java.util.Scanner;  c.pdf
using set identitiesSolutionimport java.util.Scanner; c.pdf
excellentmobilesabc
 
10 Solution#include-iostream-h- #include-conio-h- #include-process-h-.docx
10 Solution#include-iostream-h- #include-conio-h- #include-process-h-.docx10 Solution#include-iostream-h- #include-conio-h- #include-process-h-.docx
10 Solution#include-iostream-h- #include-conio-h- #include-process-h-.docx
todd991
 
FP 201 - Unit 6
FP 201 - Unit 6FP 201 - Unit 6
FP 201 - Unit 6
rohassanie
 
Struktur data (alokasi memory)
Struktur data (alokasi memory)Struktur data (alokasi memory)
Struktur data (alokasi memory)
Abbedul Thembock
 
I have to write a polynomial class linked list program and i do not .pdf
I have to write a polynomial class linked list program and i do not .pdfI have to write a polynomial class linked list program and i do not .pdf
I have to write a polynomial class linked list program and i do not .pdf
jibinsh
 
Lab Manual IV (1).pdf on C++ Programming practice
Lab Manual IV (1).pdf on C++ Programming practiceLab Manual IV (1).pdf on C++ Programming practice
Lab Manual IV (1).pdf on C++ Programming practice
ranaibrahim453
 
Help to implement delete_node get_succ get_pred walk and.pdf
Help to implement delete_node get_succ get_pred walk and.pdfHelp to implement delete_node get_succ get_pred walk and.pdf
Help to implement delete_node get_succ get_pred walk and.pdf
contact32
 
Boost.Interfaces
Boost.InterfacesBoost.Interfaces
Boost.Interfaces
melpon
 
All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2go
Moriyoshi Koizumi
 

Ähnlich wie Pointless Pointers - How to make our interfaces efficient? (20)

C++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorC++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operator
 
Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»
 
using set identitiesSolutionimport java.util.Scanner; c.pdf
using set identitiesSolutionimport java.util.Scanner;  c.pdfusing set identitiesSolutionimport java.util.Scanner;  c.pdf
using set identitiesSolutionimport java.util.Scanner; c.pdf
 
10 Solution#include-iostream-h- #include-conio-h- #include-process-h-.docx
10 Solution#include-iostream-h- #include-conio-h- #include-process-h-.docx10 Solution#include-iostream-h- #include-conio-h- #include-process-h-.docx
10 Solution#include-iostream-h- #include-conio-h- #include-process-h-.docx
 
FP 201 - Unit 6
FP 201 - Unit 6FP 201 - Unit 6
FP 201 - Unit 6
 
Struktur data (alokasi memory)
Struktur data (alokasi memory)Struktur data (alokasi memory)
Struktur data (alokasi memory)
 
I have to write a polynomial class linked list program and i do not .pdf
I have to write a polynomial class linked list program and i do not .pdfI have to write a polynomial class linked list program and i do not .pdf
I have to write a polynomial class linked list program and i do not .pdf
 
Lab Manual IV (1).pdf on C++ Programming practice
Lab Manual IV (1).pdf on C++ Programming practiceLab Manual IV (1).pdf on C++ Programming practice
Lab Manual IV (1).pdf on C++ Programming practice
 
Help to implement delete_node get_succ get_pred walk and.pdf
Help to implement delete_node get_succ get_pred walk and.pdfHelp to implement delete_node get_succ get_pred walk and.pdf
Help to implement delete_node get_succ get_pred walk and.pdf
 
C s investigatory project on telephone directory
C s  investigatory project on telephone directoryC s  investigatory project on telephone directory
C s investigatory project on telephone directory
 
Boost.Interfaces
Boost.InterfacesBoost.Interfaces
Boost.Interfaces
 
COW
COWCOW
COW
 
All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2go
 
Lk module5 pointers
Lk module5 pointersLk module5 pointers
Lk module5 pointers
 
Computer Investgatort Project (HOTEL MANAGEMENT SYSTEM)
Computer Investgatort Project (HOTEL MANAGEMENT SYSTEM)Computer Investgatort Project (HOTEL MANAGEMENT SYSTEM)
Computer Investgatort Project (HOTEL MANAGEMENT SYSTEM)
 
Mutate and Test your Tests with STAMP, Caroline Landry, Inria, Paris Open Sou...
Mutate and Test your Tests with STAMP, Caroline Landry, Inria, Paris Open Sou...Mutate and Test your Tests with STAMP, Caroline Landry, Inria, Paris Open Sou...
Mutate and Test your Tests with STAMP, Caroline Landry, Inria, Paris Open Sou...
 
C++11 & C++14
C++11 & C++14C++11 & C++14
C++11 & C++14
 
Antlr V3
Antlr V3Antlr V3
Antlr V3
 
C#7, 7.1, 7.2, 7.3 e C# 8
C#7, 7.1, 7.2, 7.3 e C# 8C#7, 7.1, 7.2, 7.3 e C# 8
C#7, 7.1, 7.2, 7.3 e C# 8
 
Chapter5.pptx
Chapter5.pptxChapter5.pptx
Chapter5.pptx
 

Mehr von Mateusz Pusz

Mehr von Mateusz Pusz (15)

Free Lunch is Over: Why is C++ so Important in the Modern World?
Free Lunch is Over: Why is C++ so Important in the Modern World?Free Lunch is Over: Why is C++ so Important in the Modern World?
Free Lunch is Over: Why is C++ so Important in the Modern World?
 
A Physical Units Library for the Next C++
A Physical Units Library for the Next C++A Physical Units Library for the Next C++
A Physical Units Library for the Next C++
 
Striving for ultimate Low Latency
Striving for ultimate Low LatencyStriving for ultimate Low Latency
Striving for ultimate Low Latency
 
Rethinking the Way We do Templates in C++
Rethinking the Way We do Templates in C++Rethinking the Way We do Templates in C++
Rethinking the Way We do Templates in C++
 
C++11 Was Only the Beginning
C++11 Was Only the BeginningC++11 Was Only the Beginning
C++11 Was Only the Beginning
 
Implementing a Physical Units Library for C++
Implementing a Physical Units Library for C++Implementing a Physical Units Library for C++
Implementing a Physical Units Library for C++
 
Effective replacement of dynamic polymorphism with std::variant
Effective replacement of dynamic polymorphism with std::variantEffective replacement of dynamic polymorphism with std::variant
Effective replacement of dynamic polymorphism with std::variant
 
Implementing Physical Units Library for C++
Implementing Physical Units Library for C++Implementing Physical Units Library for C++
Implementing Physical Units Library for C++
 
C++ Concepts and Ranges - How to use them?
C++ Concepts and Ranges - How to use them?C++ Concepts and Ranges - How to use them?
C++ Concepts and Ranges - How to use them?
 
Effective replacement of dynamic polymorphism with std::variant
Effective replacement of dynamic polymorphism with std::variantEffective replacement of dynamic polymorphism with std::variant
Effective replacement of dynamic polymorphism with std::variant
 
Git, CMake, Conan - How to ship and reuse our C++ projects?
Git, CMake, Conan - How to ship and reuse our C++ projects?Git, CMake, Conan - How to ship and reuse our C++ projects?
Git, CMake, Conan - How to ship and reuse our C++ projects?
 
Beyond C++17
Beyond C++17Beyond C++17
Beyond C++17
 
Striving for ultimate Low Latency
Striving for ultimate Low LatencyStriving for ultimate Low Latency
Striving for ultimate Low Latency
 
Small Lie in Big O
Small Lie in Big OSmall Lie in Big O
Small Lie in Big O
 
std::shared_ptr<T> - (not so) Smart hammer for every pointy nail
std::shared_ptr<T> - (not so) Smart hammer for every pointy nailstd::shared_ptr<T> - (not so) Smart hammer for every pointy nail
std::shared_ptr<T> - (not so) Smart hammer for every pointy nail
 

Kürzlich hochgeladen

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Kürzlich hochgeladen (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 

Pointless Pointers - How to make our interfaces efficient?

  • 1. Mateusz Pusz November 15, 2017 POINTLESS POINTERS HOW TO MAKE OUR INTERFACES EFFICIENT?
  • 2. code::dive 2017 | Pointless Pointers WHAT IS A POINTER? 2
  • 3. A pointer is a programming language data type whose value refers directly to (or "points to") another value stored elsewhere in the computer memory using its address. -- Wikipedia code::dive 2017 | Pointless Pointers WHAT IS A POINTER? 2
  • 4. code::dive 2017 | Pointless Pointers WHAT IS A POINTER? 3
  • 5. Pointers due to their ambiguous nature are the source of most problems and bugs in C++ code. Lack of understanding between code architect and the user results in crashes, asserts and memory leaks!!! -- Mateusz Pusz ☺ code::dive 2017 | Pointless Pointers WHAT IS A POINTER? 3
  • 6. code::dive 2017 | Pointless Pointers POINTERS MISUSE LEADS TO 4
  • 7. code::dive 2017 | Pointless Pointers POINTERS MISUSE LEADS TO Null Pointer Dereference 4
  • 8. code::dive 2017 | Pointless Pointers POINTERS MISUSE LEADS TO Null Pointer Dereference Resource leaks 4
  • 9. code::dive 2017 | Pointless Pointers POINTERS MISUSE LEADS TO Null Pointer Dereference Resource leaks Bu er Overflows 4
  • 10. code::dive 2017 | Pointless Pointers POINTERS MISUSE LEADS TO Null Pointer Dereference Resource leaks Bu er Overflows Hangs! 4
  • 11. code::dive 2017 | Pointless Pointers POINTERS MISUSE LEADS TO Null Pointer Dereference Resource leaks Bu er Overflows Hangs! Crashes! 4
  • 12. code::dive 2017 | Pointless Pointers POINTERS MISUSE LEADS TO Null Pointer Dereference Resource leaks Bu er Overflows Hangs! Crashes!Stability!!! 4
  • 13. code::dive 2017 | Pointless Pointers POINTERS MISUSE LEADS TO Null Pointer Dereference Resource leaks Bu er Overflows Hangs! Crashes!Stability!!! Security!!! 4
  • 14. B* a(A* ptr) { /* ... */; return b(ptr); } code::dive 2017 | Pointless Pointers PROBLEM DEFINITION 5
  • 15. B* a(A* ptr) { /* ... */; return b(ptr); } B* b(A* ptr) { /* ... */; return c(ptr); } code::dive 2017 | Pointless Pointers PROBLEM DEFINITION 5
  • 16. B* a(A* ptr) { /* ... */; return b(ptr); } B* b(A* ptr) { /* ... */; return c(ptr); } B* c(A* ptr) { /* ... */; return d(ptr); } code::dive 2017 | Pointless Pointers PROBLEM DEFINITION 5
  • 17. B* a(A* ptr) { /* ... */; return b(ptr); } B* b(A* ptr) { /* ... */; return c(ptr); } B* c(A* ptr) { /* ... */; return d(ptr); } B* d(A* ptr) { /* ... */; return e(ptr); } code::dive 2017 | Pointless Pointers PROBLEM DEFINITION 5
  • 18. B* a(A* ptr) { /* ... */; return b(ptr); } B* b(A* ptr) { /* ... */; return c(ptr); } B* c(A* ptr) { /* ... */; return d(ptr); } B* d(A* ptr) { /* ... */; return e(ptr); } B* e(A* ptr) { /* ... */; return f(ptr); } code::dive 2017 | Pointless Pointers PROBLEM DEFINITION 5
  • 19. B* a(A* ptr) { /* ... */; return b(ptr); } B* b(A* ptr) { /* ... */; return c(ptr); } B* c(A* ptr) { /* ... */; return d(ptr); } B* d(A* ptr) { /* ... */; return e(ptr); } B* e(A* ptr) { /* ... */; return f(ptr); } B* f(A* ptr) { /* ... */; return g(ptr); } code::dive 2017 | Pointless Pointers PROBLEM DEFINITION 5
  • 20. B* a(A* ptr) { /* ... */; return b(ptr); } B* b(A* ptr) { /* ... */; return c(ptr); } B* c(A* ptr) { /* ... */; return d(ptr); } B* d(A* ptr) { /* ... */; return e(ptr); } B* e(A* ptr) { /* ... */; return f(ptr); } B* f(A* ptr) { /* ... */; return g(ptr); } B* g(A* ptr) { /* ... */; return *ptr; } code::dive 2017 | Pointless Pointers PROBLEM DEFINITION 5
  • 21. B* a(A* ptr) { /* ... */; assert(ptr); return b(ptr); } B* b(A* ptr) { /* ... */; assert(ptr); return c(ptr); } B* c(A* ptr) { /* ... */; assert(ptr); return d(ptr); } B* d(A* ptr) { /* ... */; assert(ptr); return e(ptr); } B* e(A* ptr) { /* ... */; assert(ptr); return f(ptr); } B* f(A* ptr) { /* ... */; assert(ptr); return g(ptr); } B* g(A* ptr) { /* ... */; assert(ptr); return *ptr; } code::dive 2017 | Pointless Pointers PROBLEM DEFINITION 6
  • 22. B* a(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return b(ptr); } B* b(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return c(ptr); } B* c(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return d(ptr); } B* d(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return e(ptr); } B* e(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return f(ptr); } B* f(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return g(ptr); } B* g(A* ptr) { /* ... */; if(!ptr) throw std::invalid_argument{""}; return *ptr; } code::dive 2017 | Pointless Pointers PROBLEM DEFINITION 7
  • 23. B* func(A* arg); code::dive 2017 | Pointless Pointers QUIZ - GUESS WHAT? 8
  • 24. person* add(name* n); code::dive 2017 | Pointless Pointers QUIZ - GUESS WHAT? 9
  • 25. person* add(name* n); code::dive 2017 | Pointless Pointers QUIZ - GUESS WHAT? Is it better now? Is it enough? Do you know how to use that function? Do you know how to implement that function? 9
  • 26. person* add(name* n); void foo() { person* p = add(new name{"Mateusz Pusz"}); assert(p != nullptr); process(p->id(), p->name()); delete p; } code::dive 2017 | Pointless Pointers ADD() USAGE – TAKE #1 10
  • 27. person* add(name* n); void foo() { person* p = add(new name{"Mateusz Pusz"}); assert(p != nullptr); process(p->id(), p->name()); delete p; } code::dive 2017 | Pointless Pointers ADD() USAGE – TAKE #1 Is that a valid usage of add() interface? What are potential problems with above code? 10
  • 28. person* add(name* n); void foo() { name n{"Mateusz Pusz"}; person* p = add(&n); if(p != nullptr) process(p->id(), p->name()); } code::dive 2017 | Pointless Pointers ADD() USAGE – TAKE #2 11
  • 29. person* add(name* n); void foo() { name n{"Mateusz Pusz"}; person* p = add(&n); if(p != nullptr) process(p->id(), p->name()); } code::dive 2017 | Pointless Pointers ADD() USAGE – TAKE #2 Is that a valid usage of add() interface? 11
  • 30. person* add(name* n); void foo() { name* n = new name{"Mateusz Pusz"}; person* p = add(n); if(p != nullptr) process(p->id(), p->name()); delete n; } code::dive 2017 | Pointless Pointers ADD() USAGE – TAKE #3 12
  • 31. person* add(name* n); void foo() { name* n = new name{"Mateusz Pusz"}; person* p = add(n); if(p != nullptr) process(p->id(), p->name()); delete n; } code::dive 2017 | Pointless Pointers ADD() USAGE – TAKE #3 Is that a valid usage of add() interface? What are potential problems with above code? 12
  • 32. person* add(name* n); void foo() { name names[] = {"Mateusz Pusz", "Jan Kowalski", ""}; person* people = add(names); assert(people != nullptr); for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i) process(people[i].id(), people[i].name()); delete[] people; } code::dive 2017 | Pointless Pointers ADD() USAGE – TAKE #4 13
  • 33. person* add(name* n); void foo() { name names[] = {"Mateusz Pusz", "Jan Kowalski", ""}; person* people = add(names); assert(people != nullptr); for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i) process(people[i].id(), people[i].name()); delete[] people; } code::dive 2017 | Pointless Pointers ADD() USAGE – TAKE #4 Is that a valid usage of add() interface? What are potential problems with above code? 13
  • 34. void foo() { person* p = add(new name{"Mateusz Pusz"}); assert(p != nullptr); process(p->id(), p->name()); delete p; } void foo() { name n{"Mateusz Pusz"}; person* p = add(&n); if(p != nullptr) process(p->id(), p->name()); } void foo() { name* n = new name{"Mateusz Pusz"}; person* p = add(n); if(p != nullptr) process(p->id(), p->name()); delete n; } void foo() { name names[] = {"Mateusz Pusz", "Jan Kowalski", ""}; person* people = add(names); assert(people != nullptr); for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i) process(people[i].id(), people[i].name()); delete[] people; } code::dive 2017 | Pointless Pointers 1 2 3 4 WHICH ONE IS CORRECT? 14
  • 35. void foo() { person* p = add(new name{"Mateusz Pusz"}); assert(p != nullptr); process(p->id(), p->name()); delete p; } void foo() { name n{"Mateusz Pusz"}; person* p = add(&n); if(p != nullptr) process(p->id(), p->name()); } void foo() { name* n = new name{"Mateusz Pusz"}; person* p = add(n); if(p != nullptr) process(p->id(), p->name()); delete n; } void foo() { name names[] = {"Mateusz Pusz", "Jan Kowalski", ""}; person* people = add(names); assert(people != nullptr); for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i) process(people[i].id(), people[i].name()); delete[] people; } code::dive 2017 | Pointless Pointers 1 2 3 4 QUIZ - MATCH IMPLEMENTATION std::deque<person> people; person* add(name* n) { people.emplace_back((n != nullptr) ? *n : "anonymous"); return &people.back(); } 15
  • 36. void foo() { person* p = add(new name{"Mateusz Pusz"}); assert(p != nullptr); process(p->id(), p->name()); delete p; } void foo() { name* n = new name{"Mateusz Pusz"}; person* p = add(n); if(p != nullptr) process(p->id(), p->name()); delete n; } void foo() { name names[] = {"Mateusz Pusz", "Jan Kowalski", ""}; person* people = add(names); assert(people != nullptr); for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i) process(people[i].id(), people[i].name()); delete[] people; } code::dive 2017 | Pointless Pointers QUIZ - MATCH IMPLEMENTATION 1 void foo() { name n{"Mateusz Pusz"}; person* p = add(&n); if(p != nullptr) process(p->id(), p->name()); } 2 3 4 person* add(name* n) { assert(n); int num = 0; for(auto ptr = n; *ptr != ""; ++ptr) ++num; person* p = new person[num]; for(auto i = 0; i<num; ++i) p[i].name(n[i]); return p; } 16
  • 37. void foo() { person* p = add(new name{"Mateusz Pusz"}); assert(p != nullptr); process(p->id(), p->name()); delete p; } void foo() { name* n = new name{"Mateusz Pusz"}; person* p = add(n); if(p != nullptr) process(p->id(), p->name()); delete n; } code::dive 2017 | Pointless Pointers QUIZ - MATCH IMPLEMENTATION 1 void foo() { name n{"Mateusz Pusz"}; person* p = add(&n); if(p != nullptr) process(p->id(), p->name()); } 2 3 void foo() { name names[] = {"Mateusz Pusz", "Jan Kowalski", ""}; person* people = add(names); assert(people != nullptr); for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i) process(people[i].id(), people[i].name()); delete[] people; } 4 person* add(name* n) { assert(n != nullptr); return new person{n}; } 17
  • 38. void foo() { name* n = new name{"Mateusz Pusz"}; person* p = add(n); if(p != nullptr) process(p->id(), p->name()); delete n; } code::dive 2017 | Pointless Pointers QUIZ - MATCH IMPLEMENTATION void foo() { person* p = add(new name{"Mateusz Pusz"}); assert(p != nullptr); process(p->id(), p->name()); delete p; } void foo() { name n{"Mateusz Pusz"}; person* p = add(&n); if(p != nullptr) process(p->id(), p->name()); } 1 2 3 void foo() { name names[] = {"Mateusz Pusz", "Jan Kowalski", ""}; person* people = add(names); assert(people != nullptr); for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i) process(people[i].id(), people[i].name()); delete[] people; } 4 std::deque<person> people; person* add(name* n) { if(n == nullptr) return nullptr; auto it = find_if(begin(people), end(people), [&](person& p) { return p.name() == *n; }); if(it != end(people)) return nullptr; people.emplace_back(*n); return &people.back(); } 18
  • 39. code::dive 2017 | Pointless Pointers QUIZ - MATCH IMPLEMENTATION void foo() { person* p = add(new name{"Mateusz Pusz"}); assert(p != nullptr); process(p->id(), p->name()); delete p; } void foo() { name n{"Mateusz Pusz"}; person* p = add(&n); if(p != nullptr) process(p->id(), p->name()); } void foo() { name* n = new name{"Mateusz Pusz"}; person* p = add(n); if(p != nullptr) process(p->id(), p->name()); delete n; } void foo() { name names[] = {"Mateusz Pusz", "Jan Kowalski", ""}; person* people = add(names); assert(people != nullptr); for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i) process(people[i].id(), people[i].name()); delete[] people; } 1 2 3 4 19
  • 40. person* add(name* n); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? 20
  • 41. person* add(name* n); std::unique_ptr<person> add(std::unique_ptr<name> n); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? 20
  • 42. person* add(name* n); std::unique_ptr<person> add(std::unique_ptr<name> n); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? Do you know how to use that function? Do you know how to implement that function? 20
  • 43. person* add(name* n) { assert(n != nullptr); return new person{n}; } void foo() { person* p = add( new name{"Mateusz Pusz"}); assert(p != nullptr); process(p->id(), p->name()); delete p; } code::dive 2017 | Pointless Pointers USING C++ THE RIGHT WAY – CASE #1 21
  • 44. void foo() { auto p = add( std::make_unique<name>("Mateusz Pusz")); assert(p != nullptr); process(p->id(), p->name()); } std::unique_ptr<person> add(std::unique_ptr<name> n) { assert(n != nullptr); return std::make_unique<person>(std::move(n)); } code::dive 2017 | Pointless Pointers USING C++ THE RIGHT WAY – CASE #1 person* add(name* n) { assert(n != nullptr); return new person{n}; } void foo() { person* p = add( new name{"Mateusz Pusz"}); assert(p != nullptr); process(p->id(), p->name()); delete p; } 21
  • 45. person* add(name* n); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? 22
  • 46. person* add(name* n); person& add(std::optional<name> n); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? 22
  • 47. person* add(name* n); person& add(std::optional<name> n); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? Do you know how to use that function? Do you know how to implement that function? 22
  • 48. std::deque<person> people; person* add(name* n) { people.emplace_back( (n != nullptr) ? *n : "anonymous"); return &people.back(); } void foo() { name n{"Mateusz Pusz"}; person* p = add(&n); if(p != nullptr) process(p->id(), p->name()); } code::dive 2017 | Pointless Pointers USING C++ THE RIGHT WAY – CASE #2 23
  • 49. std::deque<person> people; person& add(std::optional<name> n) { people.emplace_back( n ? std::move(*n) : "anonymous"); return people.back(); } void foo() { person& p = add(name{"Mateusz Pusz"}); process(p.id(), p.name()); } code::dive 2017 | Pointless Pointers USING C++ THE RIGHT WAY – CASE #2 std::deque<person> people; person* add(name* n) { people.emplace_back( (n != nullptr) ? *n : "anonymous"); return &people.back(); } void foo() { name n{"Mateusz Pusz"}; person* p = add(&n); if(p != nullptr) process(p->id(), p->name()); } 23
  • 50. person* add(name* n); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? 24
  • 51. person* add(name* n); std::tuple<person&, bool> add(name n); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? 24
  • 52. person* add(name* n); std::tuple<person&, bool> add(name n); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? Do you know how to use that function? Do you know how to implement that function? 24
  • 53. std::deque<person> people; person* add(name* n) { if(n == nullptr) return nullptr; auto it = find_if( begin(people), end(people), [&](person& p) { return p.name() == *n; }); if(it != end(people)) return nullptr; people.emplace_back(*n); return &people.back(); } void foo() { name* n = new name{"Mateusz Pusz"}; person* p = add(n); if(p != nullptr) process(p->id(), p->name()); delete n; } code::dive 2017 | Pointless Pointers USING C++ THE RIGHT WAY – CASE #3 25
  • 54. std::deque<person> people; std::tuple<person&, bool> add(name n) { auto it = find_if( begin(people), end(people), [&](person& p) { return p.name() == n; }); if(it != end(people)) return { *it, false }; people.emplace_back(std::move(n)); return { people.back(), true }; } void foo() { auto r = add(name{"Mateusz Pusz"}); if(std::get<bool>(r)) process(std::get<0>(r).id(), std::get<0>(r).name()); } code::dive 2017 | Pointless Pointers USING C++ THE RIGHT WAY – CASE #3 std::deque<person> people; person* add(name* n) { if(n == nullptr) return nullptr; auto it = find_if( begin(people), end(people), [&](person& p) { return p.name() == *n; }); if(it != end(people)) return nullptr; people.emplace_back(*n); return &people.back(); } void foo() { name* n = new name{"Mateusz Pusz"}; person* p = add(n); if(p != nullptr) process(p->id(), p->name()); delete n; } 25
  • 55. person* add(name* n); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? 26
  • 56. person* add(name* n); std::vector<person> add(std::vector<name> names); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? 26
  • 57. person* add(name* n); std::vector<person> add(std::vector<name> names); code::dive 2017 | Pointless Pointers IS THERE A BETTER SOLUTION? Do you know how to use that function? Do you know how to implement that function? 26
  • 58. person* add(name* n) { assert(n); int num = 0; for(auto ptr = n; *ptr != ""; ++ptr) ++num; person* p = new person[num]; for(auto i = 0; i<num; ++i) p[i].name(n[i]); return p; } void foo() { name names[] = {"Mateusz Pusz", "Jan Kowalski", ""}; person* people = add(names); assert(people != nullptr); for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i) process(people[i].id(), people[i].name()); delete[] people; } code::dive 2017 | Pointless Pointers USING C++ THE RIGHT WAY – CASE #4 27
  • 59. std::vector<person> add(std::vector<name> names) { std::vector<person> p; p.reserve(names.size()); for(auto& n : names) p.emplace_back(std::move(n)); return p; } void foo() { auto people = add({"Mateusz Pusz", "Jan Kowalski"}); for(auto& p : people) process(p.id(), p.name()); } code::dive 2017 | Pointless Pointers USING C++ THE RIGHT WAY – CASE #4 person* add(name* n) { assert(n); int num = 0; for(auto ptr = n; *ptr != ""; ++ptr) ++num; person* p = new person[num]; for(auto i = 0; i<num; ++i) p[i].name(n[i]); return p; } void foo() { name names[] = {"Mateusz Pusz", "Jan Kowalski", ""}; person* people = add(names); assert(people != nullptr); for(int i=0; i<sizeof(names)/sizeof(*names) - 1; ++i) process(people[i].id(), people[i].name()); delete[] people; } 27
  • 60.
  • 61. ARGUMENT TYPE POINTER ARGUMENT DECLARATION Mandatory big value void foo(A* in); Output function argument void foo(A* out); Array void foo(A* array); Optional value void foo(A* opt); Ownership passing void foo(A* ptr); code::dive 2017 | Pointless Pointers POINTERS USAGE IN ANSI C 29
  • 62. ARGUMENT TYPE POINTER ARGUMENT DECLARATION Mandatory big value void foo(A* in); Output function argument void foo(A* out); Array void foo(A* array); Optional value void foo(A* opt); Ownership passing void foo(A* ptr); code::dive 2017 | Pointless Pointers POINTERS USAGE IN ANSI C Pointer ambiguity makes it really hard to understand the intent of the interface author. 29
  • 63. ARGUMENT TYPE POINTER ARGUMENT DECLARATION Mandatory big value void foo(const A& in); Output function argument A foo(); or std::tuple<...> foo(); or void foo(A& out); Array void foo(const std::vector<A>& a); Optional value void foo(std::optional<A> opt); or void foo(A* opt); Ownership passing void foo(std::unique_ptr<A> ptr); code::dive 2017 | Pointless Pointers DOING IT C++ WAY 30
  • 64. ARGUMENT TYPE POINTER ARGUMENT DECLARATION Mandatory big value void foo(const A& in); Output function argument A foo(); or std::tuple<...> foo(); or void foo(A& out); Array void foo(const std::vector<A>& a); Optional value void foo(std::optional<A> opt); or void foo(A* opt); Ownership passing void foo(std::unique_ptr<A> ptr); code::dive 2017 | Pointless Pointers DOING IT C++ WAY Use above Modern C++ constructs to explicitly state your design intent. 30
  • 65. B foo(std::optional<A> arg); const A& foo(const std::array<A, 3>& arg); std::unique_ptr<B> foo(A arg); std::vector<B> foo(const A& arg); code::dive 2017 | Pointless Pointers QUIZ – GUESS WHAT? 31
  • 66. int count_lower(const char* ptr, size_t size); void add_2(int* ptr, size_t size); code::dive 2017 | Pointless Pointers C++17 AND C++20: WHAT ABOUT POINTER AND A SIZE ANSI C -> C++14 ANSI C -> C++14 32
  • 67. int count_lower(const char* ptr, size_t size); void add_2(int* ptr, size_t size); int count_lower(std::string_view txt); void add_2(std::span<int> array); code::dive 2017 | Pointless Pointers C++17 AND C++20: WHAT ABOUT POINTER AND A SIZE ANSI C -> C++14 ANSI C -> C++14 C++17 C++20 32
  • 69. C++ is a powerful tool: • strong type system • better abstractions • templates • C++ STD library code::dive 2017 | Pointless Pointers C++ IS NOT ANSI C!!! 34