Slide 1

Slide 1 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 1/168 Programming with Contracts in C++20 Björn Fahller

Slide 2

Slide 2 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 2/168 What is a contract? contract noun con· tract | \ˈkän-ˌtrakt \ Definition of contract (Entry 1 of 3) 1: a: binding agreement between two or more persons or parties - especially : one legally enforceable // If he breaks the contract, he'll be sued. b: a business arrangement for the supply of goods or services at a fixed price // make parts on contract c: the act of marriage or an agreement to marry 2: a document describing the terms of a contract // Have you signed the contract yet? 3: the final bid to win a specified number of tricks in bridge 4: an order or arrangement for a hired assassin to kill someone // His enemies put out a contract on him. https:////w.merriam-webster.com/dictionary/contract

Slide 3

Slide 3 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 3/168 What is a contract? contract noun con· tract | \ˈkän-ˌtrakt \ Definition of contract (Entry 1 of 3) 1: a: binding agreement between two or more persons or parties - especially : one legally enforceable // If he breaks the contract, he'll be sued. b: a business arrangement for the supply of goods or services at a fixed price // make parts on contract c: the act of marriage or an agreement to marry 2: a document describing the terms of a contract // Have you signed the contract yet? 3: the final bid to win a specified number of tricks in bridge 4: an order or arrangement for a hired assassin to kill someone // His enemies put out a contract on him. https:////w.merriam-webster.com/dictionary/contract In SW design: A formalised agreement, regarding program correctness, between a user and the implementation of a component.

Slide 4

Slide 4 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 4/168 What is a contract? contract noun con· tract | \ˈkän-ˌtrakt \ Definition of contract (Entry 1 of 3) 1: a: binding agreement between two or more persons or parties - especially : one legally enforceable // If he breaks the contract, he'll be sued. b: a business arrangement for the supply of goods or services at a fixed price // make parts on contract c: the act of marriage or an agreement to marry 2: a document describing the terms of a contract // Have you signed the contract yet? 3: the final bid to win a specified number of tricks in bridge 4: an order or arrangement for a hired assassin to kill someone // His enemies put out a contract on him. https:////w.merriam-webster.com/dictionary/contract In SW design: A formalised agreement, regarding program correctness, between a user and the implementation of a component.

Slide 5

Slide 5 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 5/168 Contracts ● Object-oriented Software Construction – Bertrand Meyer - 1988 – ISBN 978-0136290490

Slide 6

Slide 6 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 6/168 ● Preconditions ● Postconditions ● Class invariants Contracts

Slide 7

Slide 7 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 7/168 Ringbuffer example ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 8

Slide 8 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 8/168 Ringbuffer example ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 9

Slide 9 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 9/168 Ringbuffer example 1 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 10

Slide 10 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 10/168 Ringbuffer example 1 2 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 11

Slide 11 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 11/168 Ringbuffer example 1 2 5 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 12

Slide 12 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 12/168 Ringbuffer example 1 2 5 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 13

Slide 13 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 13/168 Ringbuffer example 2 5 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 14

Slide 14 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 14/168 Ringbuffer example 2 5 8 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 15

Slide 15 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 15/168 Ringbuffer example 2 5 8 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 16

Slide 16 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 16/168 Ringbuffer example 5 8 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 17

Slide 17 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 17/168 Ringbuffer example 5 8 11 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 18

Slide 18 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 18/168 Ringbuffer example 5 8 11 13 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 19

Slide 19 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 19/168 Ringbuffer example 5 8 11 13 15 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 20

Slide 20 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 20/168 Ringbuffer example 5 8 11 13 15 21 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 21

Slide 21 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 21/168 Ringbuffer example 5 8 11 13 15 21 23 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 22

Slide 22 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 22/168 Ringbuffer example 5 8 11 13 15 21 23 24 ringbuffer b; b.push_back(1); b.push_back(2); b.push_back(5); b.pop_front(); // 1 b.push_back(8); b.pop_front(); // 2 b.push_back(11); b.push_back(13); b.push_back(15); b.push_back(21); b.push_back(23); b.push_back(24);

Slide 23

Slide 23 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 23/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); T pop_front(); };

Slide 24

Slide 24 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 24/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); T pop_front(); }; Precondition:

Slide 25

Slide 25 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 25/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct.

Slide 26

Slide 26 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 26/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct. A precondition may refer to parameter values or the objects state, or both

Slide 27

Slide 27 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 27/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct.

Slide 28

Slide 28 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 28/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct. It almost never makes sense to have a precondition on a default constructor!

Slide 29

Slide 29 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 29/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct.

Slide 30

Slide 30 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 30/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct. Functions that query the state of an object rarely has any preconditions.

Slide 31

Slide 31 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 31/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct.

Slide 32

Slide 32 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 32/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct. Choose between: Define behaviour when full, or make not-full a precondition.

Slide 33

Slide 33 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 33/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); // requires: size() < N T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct.

Slide 34

Slide 34 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 34/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); // requires: size() < N T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct.

Slide 35

Slide 35 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 35/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); // requires: size() < N T pop_front(); }; Precondition: An obligation that the caller must fulfill for the program to be correct. Choose between: Define behaviour when empty, or make not-empty a precondition.

Slide 36

Slide 36 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 36/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); // requires: size() < N T pop_front(); // requires: size() > 0 }; Precondition: An obligation that the caller must fulfill for the program to be correct.

Slide 37

Slide 37 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 37/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); // requires: size() < N T pop_front(); // requires: size() > 0 }; Postcondition:

Slide 38

Slide 38 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 38/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); // requires: size() < N T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 39

Slide 39 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 39/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); // requires: size() < N T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call. A postcondition may refer to return value or the objects state, or both, sometimes dependent on parameter values

Slide 40

Slide 40 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 40/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); int size() const; void push_back(T); // requires: size() < N T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 41

Slide 41 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 41/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; void push_back(T); // requires: size() < N T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 42

Slide 42 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 42/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; void push_back(T); // requires: size() < N T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 43

Slide 43 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 43/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; void push_back(T); // requires: size() < N T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 44

Slide 44 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 44/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; void push_back(T); // requires: size() < N // ensures: size() /= old size()+1 T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 45

Slide 45 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 45/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 46

Slide 46 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 46/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 47

Slide 47 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 47/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 48

Slide 48 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 48/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call. What if an exception is thrown?

Slide 49

Slide 49 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 49/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call. Postconditions handles return. If an exception is thrown, there is no post condition.

Slide 50

Slide 50 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 50/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 51

Slide 51 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 51/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 52

Slide 52 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 52/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 const T& front() const; void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 53

Slide 53 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 53/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Postcondition: A guarantee from the implementation regarding the effect of a legal call.

Slide 54

Slide 54 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 54/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& top() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Postcondition: A guarantee from the implementation regarding the effect of a legal call. It does not make sense to try and express the returned value from the history of pushes and pops as a post condition.

Slide 55

Slide 55 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 55/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // ensures: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Class invariant:

Slide 56

Slide 56 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 56/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // ensures: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Class invariant: Something that is always* true for a valid instance * outside public API

Slide 57

Slide 57 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 57/168 Ringbuffer example template class ringbuffer { public: ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // ensures: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Class invariant: Something that is always* true for a valid instance * outside public API A class invariant always refers to state, and must be true even when exceptions are thrown.

Slide 58

Slide 58 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 58/168 Ringbuffer example template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // ensures: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Class invariant: Something that is always* true for a valid instance * outside public API

Slide 59

Slide 59 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 59/168 Ringbuffer example template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // ensures: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Class invariant: Something that is always* true for a valid instance * outside public API What about a moved-from object?

Slide 60

Slide 60 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 60/168 Ringbuffer example template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // ensures: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Contracts and templates

Slide 61

Slide 61 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 61/168 Ringbuffer example template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // ensures: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Contracts and templates What about specializations?

Slide 62

Slide 62 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 62/168 Ringbuffer example template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 virtual int size() const = 0; virtual const T& back() const = 0; // requires: size() > 0 virtual const T& front() const = 0; // requires: size() > 0 virtual void push_back(T t) = 0; // requires: size() < N // ensures: size() /= old size()+1 // back() /= t virtual T pop_front() = 0; // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Contracts and inheritance:

Slide 63

Slide 63 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 63/168 Ringbuffer example template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 virtual int size() const = 0; virtual const T& back() const = 0; // requires: size() > 0 virtual const T& front() const = 0; // requires: size() > 0 virtual void push_back(T t) = 0; // requires: size() < N // ensures: size() /= old size()+1 // back() /= t virtual T pop_front() = 0; // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Contracts and inheritance: A subcontractor may have more relaxed pre- conditions

Slide 64

Slide 64 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 64/168 Ringbuffer example template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 virtual int size() const = 0; virtual const T& back() const = 0; // requires: size() > 0 virtual const T& front() const = 0; // requires: size() > 0 virtual void push_back(T t) = 0; // requires: size() < N // ensures: size() /= old size()+1 // back() /= t virtual T pop_front() = 0; // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Contracts and inheritance: A subcontractor may have more relaxed pre- conditions and stricter post- conditions

Slide 65

Slide 65 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 65/168 Why bother?

Slide 66

Slide 66 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 66/168 Why bother? 1)It can make interfaces much clearer

Slide 67

Slide 67 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 67/168 Why bother? 1)It can make interfaces much clearer 2)It can make debugging much easier

Slide 68

Slide 68 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 68/168 Why bother? 1)It can make interfaces much clearer 2)It can make debugging much easier 3)It removes defensive checks

Slide 69

Slide 69 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 69/168 Who dunnit? guilty client implementation violation precondition postcondition invariant

Slide 70

Slide 70 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 70/168 Who dunnit? guilty client implementation violation precondition postcondition invariant Elementary, Dr. Watson

Slide 71

Slide 71 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 71/168 Who dunnit? guilty client implementation violation precondition postcondition invariant

Slide 72

Slide 72 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 72/168 Who dunnit? guilty client implementation violation precondition postcondition invariant

Slide 73

Slide 73 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 73/168 Who dunnit? guilty client implementation violation precondition postcondition invariant

Slide 74

Slide 74 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 74/168 Who dunnit? guilty client implementation violation precondition postcondition invariant

Slide 75

Slide 75 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 75/168 Who dunnit? guilty client implementation violation precondition postcondition invariant

Slide 76

Slide 76 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 76/168 Who dunnit? guilty client implementation violation precondition postcondition invariant

Slide 77

Slide 77 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 77/168 Who dunnit? guilty client implementation violation precondition postcondition invariant Or you have a bad contract!

Slide 78

Slide 78 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 78/168 Contracts in C++20

Slide 79

Slide 79 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 79/168 Contracts in C++20

Slide 80

Slide 80 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 80/168 Contracts in C++20 Description of contract attribute declarations and semantics here (4 pages)

Slide 81

Slide 81 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 81/168 Contracts in C++20 Description of contract violation handlers

Slide 82

Slide 82 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 82/168 Contracts in C++20 Meaning for virtual functions (1 paragraph)

Slide 83

Slide 83 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 83/168 Contracts in C++20 Contracts and templates (1 non-formative sentence)

Slide 84

Slide 84 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 84/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1

Slide 85

Slide 85 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 85/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1 Pre condition

Slide 86

Slide 86 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 86/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1 Pre condition template void func(std/:unique_ptr p) [[ expects : p /= nullptr ]];

Slide 87

Slide 87 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 87/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1 Optional level template void func(std/:unique_ptr p) [[ expects : p /= nullptr ]];

Slide 88

Slide 88 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 88/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1 Optional level template void func(std/:unique_ptr p) [[ expects axiom : p /= nullptr ]];

Slide 89

Slide 89 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 89/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1 Post condition

Slide 90

Slide 90 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 90/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1 template T prev(T v) [[ expects : v > 0 ]] [[ ensures audit r : r + 1 /= v ]]; Post condition

Slide 91

Slide 91 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 91/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1 template T prev(T v) [[ expects : v > 0 ]] [[ ensures audit r : r + 1 /= v ]]; Name for return value to use in conditional expression Post condition

Slide 92

Slide 92 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 92/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1 Generic assertion

Slide 93

Slide 93 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 93/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1 Generic assertion for (auto p : pointers) { [[ assert audit: p /= nullptr ]]; func(p); }

Slide 94

Slide 94 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 94/168 Contract attributes in C++20 9.11.4.1 Syntax [dcl.attr.contract.syn] 1# Contract attributes are used to specify preconditions, postconditions, and assertions for functions. contract-attribute-specifier: [ [ expects contract-level opt : conditional-expression ] ] [ [ ensures contract-level opt identifier opt : conditional-expression ] ] [ [ assert contract-level opt : conditional-expression ] ] contract-level: default audit axiom An ambiguity between a contract-level and an identifier is resolved in favor of contract-level. http://eel.is/c/+draft/dcl.attr.contract#syn-1 There are no class invariants!

Slide 95

Slide 95 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 95/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 96

Slide 96 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 96/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 97

Slide 97 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 97/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; No support for class invariants, so might as well leave as comment.

Slide 98

Slide 98 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 98/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer(); // ensures: size() /= 0 int size() const; const T& back() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 99

Slide 99 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 99/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N ringbuffer() [[ ensures: size() /= 0 ]]; int size() const; const T& back() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 100

Slide 100 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 100/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() < = N ringbuffer() [[ ensures: size() /= 0 ]]; int size() const; const T& back() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; :6:15: error: use of undeclared identifier 'size' [[ ensures: size() /= 0 ]];

Slide 101

Slide 101 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 101/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() < = N ringbuffer() [[ ensures: size() /= 0 ]]; int size() const; const T& back() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; :6:15: error: use of undeclared identifier 'size' [[ ensures: size() /= 0 ]]; Contract attributes are declarations that can only refer to identifiers seen earlier.

Slide 102

Slide 102 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 102/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() < = N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Contract attributes are declarations that can only refer to identifiers seen earlier.

Slide 103

Slide 103 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 103/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const; // requires: size() > 0 const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 104

Slide 104 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 104/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 105

Slide 105 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 105/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const; // requires: size() > 0 void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 106

Slide 106 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 106/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 107

Slide 107 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 107/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t); // requires: size() < N // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 108

Slide 108 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 108/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]]; // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 109

Slide 109 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 109/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]]; // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 110

Slide 110 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 110/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]]; // ensures: size() /= old size()+1 // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; There is no way to refer to previous state so this cannot be expressed!

Slide 111

Slide 111 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 111/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]] [[ ensures: size() > 0 ]]; // incremented // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 112

Slide 112 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 112/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]]; [[ ensures: size() > 0 ]]; // incremented // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 113

Slide 113 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 113/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]]; [[ ensures: size() > 0 ]]; // incremented // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; 6# If a function has multiple preconditions, their evaluation (if any) will be performed in the order they appear lexically. If a function has multiple postconditions, their evaluation (if any) will be performed in the order they appear lexically. [ Example: void f(int * p) [[expects: p != nullptr]] // #1 [[ensures: *p == 1]] // #3 [[expects: *p == 0]] // #2 { *p = 1; } — end example ] http://eel.is/c/+draft/dcl.attr.contract#cond-6

Slide 114

Slide 114 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 114/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]]; [[ ensures: size() > 0 ]]; // incremented // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; 6# If a function has multiple preconditions, their evaluation (if any) will be performed in the order they appear lexically. If a function has multiple postconditions, their evaluation (if any) will be performed in the order they appear lexically. [ Example: void f(int * p) [[expects: p != nullptr]] // #1 [[ensures: *p == 1]] // #3 [[expects: *p == 0]] // #2 { *p = 1; } — end example ] http://eel.is/c/+draft/dcl.attr.contract#cond-6

Slide 115

Slide 115 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 115/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]] [[ ensures: size() > 0 ]]; // incremented // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; 7# If a postcondition odr-uses ([basic.def.odr]) a parameter in its predicate and the function body makes direct or indirect modifications of the value of that parameter, the behavior is undefined. [ Example: int f(int x) [[ensures r: r == x]] { return ++x; // undefined behavior } ... http://eel.is/c/+draft/dcl.attr.contract#cond-7

Slide 116

Slide 116 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 116/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]] [[ ensures: size() > 0 ]]; // incremented // back() /= t T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; 7# If a postcondition odr-uses ([basic.def.odr]) a parameter in its predicate and the function body makes direct or indirect modifications of the value of that parameter, the behavior is undefined. [ Example: int f(int x) [[ensures r: r == x]] { return ++x; // undefined behavior } ... http://eel.is/c/+draft/dcl.attr.contract#cond-7 So the validity of the post condition declaration depends on how the function is implemented

Slide 117

Slide 117 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 117/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]] [[ ensures: size() > 0 ]] // incremented [[ ensures: back() /= t ]]; T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); }; Potentially dangerous

Slide 118

Slide 118 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 118/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]] [[ ensures: size() > 0 ]] // incremented [[ ensures: back() /= t ]]; T pop_front(); // requires: size() > 0 // ensures: size() /= old size()-1 // return /= old front(); };

Slide 119

Slide 119 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 119/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]] [[ ensures: size() > 0 ]] // incremented [[ ensures: back() /= t ]]; T pop_front() [[ expects: size() > 0 ]]; // ensures: size() /= old size()-1 // return /= old front(); };

Slide 120

Slide 120 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 120/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]] [[ ensures: size() > 0 ]] // incremented [[ ensures: back() /= t ]]; T pop_front() [[ expects: size() > 0 ]]; // ensures: size() /= old size()-1 // return /= old front(); };

Slide 121

Slide 121 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 121/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]] [[ ensures: size() > 0 ]] // incremented [[ ensures: back() /= t ]]; T pop_front() [[ expects: size() > 0 ]] [[ ensures: size() < N ]]; // decremented // return /= old front(); };

Slide 122

Slide 122 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 122/168 Using C++20 contract attributes for ringbuffer template class ringbuffer { public: // invariant: size() /= 0 /& size() /= N int size() const; ringbuffer() [[ ensures: size() /= 0 ]]; const T& back() const [[ expects: size() > 0 ]]; const T& front() const [[ expects: size() > 0 ]]; void push_back(T t) [[ expects: size() < N ]] [[ ensures: size() > 0 ]] // incremented [[ ensures: back() /= t ]]; T pop_front() [[ expects: size() > 0 ]] [[ ensures: size() < N ]]; // decremented // return /= old front(); }; Cannot express condition with previous state so might as well leave as comment

Slide 123

Slide 123 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 123/168 Virtual functions and contracts in C++20

Slide 124

Slide 124 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 124/168 Virtual functions and contracts in C++20 If an overriding function specifies contract conditions ([dcl.attr.contract]), it shall specify the same list of contract conditions as its overridden functions; no diagnostic is required if corresponding conditions will always evaluate to the same value. Otherwise, it is considered to have the list of contract conditions from one of its overridden functions; ... http://eel.is/c/+draft/class.virtual#19

Slide 125

Slide 125 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 125/168 Virtual functions and contracts in C++20 If an overriding function specifies contract conditions ([dcl.attr.contract]), it shall specify the same list of contract conditions as its overridden functions; no diagnostic is required if corresponding conditions will always evaluate to the same value. Otherwise, it is considered to have the list of contract conditions from one of its overridden functions; ... http://eel.is/c/+draft/class.virtual#19

Slide 126

Slide 126 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 126/168 Virtual functions and contracts in C++20 If an overriding function specifies contract conditions ([dcl.attr.contract]), it shall specify the same list of contract conditions as its overridden functions; no diagnostic is required if corresponding conditions will always evaluate to the same value. Otherwise, it is considered to have the list of contract conditions from one of its overridden functions; ... http://eel.is/c/+draft/class.virtual#19

Slide 127

Slide 127 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 127/168 Function pointers and contracts in C++20

Slide 128

Slide 128 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 128/168 Function pointers and contracts in C++20 3 #[ Note: A function pointer cannot include contract conditions. [ Example: typedef int (*fpt)(int) [[ensures r: r /= 0]]; // error: contract condition not on a function declaration int g(int x) [[expects: x /= 0]] [[ensures r: r > x]] { return x+1; } int (*pf)(int) = g; // OK int x = pf(5); // contract conditions of g are checked — end example ] — end note ] http://eel.is/c/+draft/dcl.attr.contract#cond-3

Slide 129

Slide 129 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 129/168 Function pointers and contracts in C++20 3 #[ Note: A function pointer cannot include contract conditions. [ Example: typedef int (*fpt)(int) [[ensures r: r /= 0]]; // error: contract condition not on a function declaration int g(int x) [[expects: x /= 0]] [[ensures r: r > x]] { return x+1; } int (*pf)(int) = g; // OK int x = pf(5); // contract conditions of g are checked — end example ] — end note ] http://eel.is/c/+draft/dcl.attr.contract#cond-3 In other words, it is the responsibility of a function implementation to enforce its contracts, not the caller.

Slide 130

Slide 130 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 130/168 Let’s explore! https://github.com/arcosuc3m/clang-contracts Fork from clang-6 http://fragata.arcos.inf.uc3m.es/#

Slide 131

Slide 131 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 131/168 Policing contracts in C++20

Slide 132

Slide 132 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 132/168 Policing contracts in C++20 3# A translation may be performed with one of the following build levels: off, default, or audit. A translation with build level set to off performs no checking for any contract. A translation with build level set to default performs checking for default contracts. A translation with build level set to audit performs checking for default and audit contracts. If no build level is explicitly selected, the build level is default. The mechanism for selecting the build level is implementation-defined. The translation of a program consisting of translation units where the build level is not the same in all translation units is conditionally- supported. There should be no programmatic way of setting, modifying, or querying the build level of a translation unit. http://eel.is/c/+draft/dcl.attr.contract#check-3

Slide 133

Slide 133 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 133/168 Policing contracts in C++20 3# A translation may be performed with one of the following build levels: off, default, or audit. A translation with build level set to off performs no checking for any contract. A translation with build level set to default performs checking for default contracts. A translation with build level set to audit performs checking for default and audit contracts. If no build level is explicitly selected, the build level is default. The mechanism for selecting the build level is implementation-defined. The translation of a program consisting of translation units where the build level is not the same in all translation units is conditionally- supported. There should be no programmatic way of setting, modifying, or querying the build level of a translation unit. http://eel.is/c/+draft/dcl.attr.contract#check-3

Slide 134

Slide 134 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 134/168 Policing contracts in C++20 3# A translation may be performed with one of the following build levels: off, default, or audit. A translation with build level set to off performs no checking for any contract. A translation with build level set to default performs checking for default contracts. A translation with build level set to audit performs checking for default and audit contracts. If no build level is explicitly selected, the build level is default. The mechanism for selecting the build level is implementation-defined. The translation of a program consisting of translation units where the build level is not the same in all translation units is conditionally- supported. There should be no programmatic way of setting, modifying, or querying the build level of a translation unit. http://eel.is/c/+draft/dcl.attr.contract#check-3

Slide 135

Slide 135 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 135/168 Policing contracts in C++20 3# A translation may be performed with one of the following build levels: off, default, or audit. A translation with build level set to off performs no checking for any contract. A translation with build level set to default performs checking for default contracts. A translation with build level set to audit performs checking for default and audit contracts. If no build level is explicitly selected, the build level is default. The mechanism for selecting the build level is implementation-defined. The translation of a program consisting of translation units where the build level is not the same in all translation units is conditionally- supported. There should be no programmatic way of setting, modifying, or querying the build level of a translation unit. http://eel.is/c/+draft/dcl.attr.contract#check-3

Slide 136

Slide 136 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 136/168 Policing contracts in C++20 3# A translation may be performed with one of the following build levels: off, default, or audit. A translation with build level set to off performs no checking for any contract. A translation with build level set to default performs checking for default contracts. A translation with build level set to audit performs checking for default and audit contracts. If no build level is explicitly selected, the build level is default. The mechanism for selecting the build level is implementation-defined. The translation of a program consisting of translation units where the build level is not the same in all translation units is conditionally- supported. There should be no programmatic way of setting, modifying, or querying the build level of a translation unit. http://eel.is/c/+draft/dcl.attr.contract#check-3

Slide 137

Slide 137 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 137/168 Policing contracts in C++20 3# A translation may be performed with one of the following build levels: off, default, or audit. A translation with build level set to off performs no checking for any contract. A translation with build level set to default performs checking for default contracts. A translation with build level set to audit performs checking for default and audit contracts. If no build level is explicitly selected, the build level is default. The mechanism for selecting the build level is implementation-defined. The translation of a program consisting of translation units where the build level is not the same in all translation units is conditionally- supported. There should be no programmatic way of setting, modifying, or querying the build level of a translation unit. http://eel.is/c/+draft/dcl.attr.contract#check-3

Slide 138

Slide 138 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 138/168 Policing contracts in C++20 3# A translation may be performed with one of the following build levels: off, default, or audit. A translation with build level set to off performs no checking for any contract. A translation with build level set to default performs checking for default contracts. A translation with build level set to audit performs checking for default and audit contracts. If no build level is explicitly selected, the build level is default. The mechanism for selecting the build level is implementation-defined. The translation of a program consisting of translation units where the build level is not the same in all translation units is conditionally- supported. There should be no programmatic way of setting, modifying, or querying the build level of a translation unit. http://eel.is/c/+draft/dcl.attr.contract#check-3

Slide 139

Slide 139 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 139/168 Policing contracts in C++20 3# A translation may be performed with one of the following build levels: off, default, or audit. A translation with build level set to off performs no checking for any contract. A translation with build level set to default performs checking for default contracts. A translation with build level set to audit performs checking for default and audit contracts. If no build level is explicitly selected, the build level is default. The mechanism for selecting the build level is implementation-defined. The translation of a program consisting of translation units where the build level is not the same in all translation units is conditionally- supported. There should be no programmatic way of setting, modifying, or querying the build level of a translation unit. http://eel.is/c/+draft/dcl.attr.contract#check-3 3.7 [defns.cond.supp] conditionally-supported program construct that an implementation is not required to support [ Note: Each implementation documents all conditionally-supported constructs that it does not support. — end note ] http://eel.is/c/+draft/intro.defs#defns.cond.supp

Slide 140

Slide 140 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 140/168 Policing contracts in C++20 3# A translation may be performed with one of the following build levels: off, default, or audit. A translation with build level set to off performs no checking for any contract. A translation with build level set to default performs checking for default contracts. A translation with build level set to audit performs checking for default and audit contracts. If no build level is explicitly selected, the build level is default. The mechanism for selecting the build level is implementation-defined. The translation of a program consisting of translation units where the build level is not the same in all translation units is conditionally- supported. There should be no programmatic way of setting, modifying, or querying the build level of a translation unit. http://eel.is/c/+draft/dcl.attr.contract#check-3

Slide 141

Slide 141 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 141/168 Let’s explore! https://github.com/arcosuc3m/clang-contracts Fork from clang-6 http://fragata.arcos.inf.uc3m.es/#

Slide 142

Slide 142 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 142/168 Let’s explore! https://github.com/arcosuc3m/clang-contracts Fork from clang-6 http://fragata.arcos.inf.uc3m.es/# -build-level=(off|default|audit)

Slide 143

Slide 143 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 143/168 When contracts are violated in C++20

Slide 144

Slide 144 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 144/168 When contracts are violated in C++20 5# The violation handler of a program is a function of type “noexcept opt function of (lvalue reference to const std/:contract_ violation) returning void”. The violation handler is invoked when the predicate of a checked contract evaluates to false (called a contract violation). There should be no programmatic way of setting or modifying the violation handler. It is implementation-defined how the violation handler is established for a program and how the std /: contract_ violation argument value is set, except as specified below. If a precondition is violated, the source location of the violation is implementation- defined. [ Note: Implementations are encouraged but not required to report the caller site. — end note ] If a postcondition is violated, the source location of the violation is the source location of the function definition. If an assertion is violated, the source location of the violation is the source location of the statement to which the assertion is applied. http://eel.is/c/+draft/dcl.attr.contract#check-5

Slide 145

Slide 145 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 145/168 When contracts are violated in C++20 5# The violation handler of a program is a function of type “noexcept opt function of (lvalue reference to const std/:contract_ violation) returning void”. The violation handler is invoked when the predicate of a checked contract evaluates to false (called a contract violation). There should be no programmatic way of setting or modifying the violation handler. It is implementation-defined how the violation handler is established for a program and how the std /: contract_ violation argument value is set, except as specified below. If a precondition is violated, the source location of the violation is implementation- defined. [ Note: Implementations are encouraged but not required to report the caller site. — end note ] If a postcondition is violated, the source location of the violation is the source location of the function definition. If an assertion is violated, the source location of the violation is the source location of the statement to which the assertion is applied. http://eel.is/c/+draft/dcl.attr.contract#check-5

Slide 146

Slide 146 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 146/168 When contracts are violated in C++20 5# The violation handler of a program is a function of type “noexcept opt function of (lvalue reference to const std/:contract_ violation) returning void”. The violation handler is invoked when the predicate of a checked contract evaluates to false (called a contract violation). There should be no programmatic way of setting or modifying the violation handler. It is implementation-defined how the violation handler is established for a program and how the std /: contract_ violation argument value is set, except as specified below. If a precondition is violated, the source location of the violation is implementation- defined. [ Note: Implementations are encouraged but not required to report the caller site. — end note ] If a postcondition is violated, the source location of the violation is the source location of the function definition. If an assertion is violated, the source location of the violation is the source location of the statement to which the assertion is applied. http://eel.is/c/+draft/dcl.attr.contract#check-5 16.8.2 Class contract_ violation [support.contract.cviol] namespace std { class contract_violation { public: uint_least32_t line_number() const noexcept; string_view file_name() const noexcept; string_view function_name() const noexcept; string_view comment() const noexcept; string_view assertion_level() const noexcept; }; } http://eel.is/c/+draft/support.contract.cviol

Slide 147

Slide 147 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 147/168 When contracts are violated in C++20 5# The violation handler of a program is a function of type “noexcept opt function of (lvalue reference to const std/:contract_ violation) returning void”. The violation handler is invoked when the predicate of a checked contract evaluates to false (called a contract violation). There should be no programmatic way of setting or modifying the violation handler. It is implementation-defined how the violation handler is established for a program and how the std /: contract_ violation argument value is set, except as specified below. If a precondition is violated, the source location of the violation is implementation- defined. [ Note: Implementations are encouraged but not required to report the caller site. — end note ] If a postcondition is violated, the source location of the violation is the source location of the function definition. If an assertion is violated, the source location of the violation is the source location of the statement to which the assertion is applied. http://eel.is/c/+draft/dcl.attr.contract#check-5

Slide 148

Slide 148 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 148/168 When contracts are violated in C++20 5# The violation handler of a program is a function of type “noexcept opt function of (lvalue reference to const std/:contract_ violation) returning void”. The violation handler is invoked when the predicate of a checked contract evaluates to false (called a contract violation). There should be no programmatic way of setting or modifying the violation handler. It is implementation-defined how the violation handler is established for a program and how the std /: contract_ violation argument value is set, except as specified below. If a precondition is violated, the source location of the violation is implementation- defined. [ Note: Implementations are encouraged but not required to report the caller site. — end note ] If a postcondition is violated, the source location of the violation is the source location of the function definition. If an assertion is violated, the source location of the violation is the source location of the statement to which the assertion is applied. http://eel.is/c/+draft/dcl.attr.contract#check-5

Slide 149

Slide 149 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 149/168 When contracts are violated in C++20 5# The violation handler of a program is a function of type “noexcept opt function of (lvalue reference to const std/:contract_ violation) returning void”. The violation handler is invoked when the predicate of a checked contract evaluates to false (called a contract violation). There should be no programmatic way of setting or modifying the violation handler. It is implementation-defined how the violation handler is established for a program and how the std /: contract_ violation argument value is set, except as specified below. If a precondition is violated, the source location of the violation is implementation- defined. [ Note: Implementations are encouraged but not required to report the caller site. — end note ] If a postcondition is violated, the source location of the violation is the source location of the function definition. If an assertion is violated, the source location of the violation is the source location of the statement to which the assertion is applied. http://eel.is/c/+draft/dcl.attr.contract#check-5

Slide 150

Slide 150 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 150/168 Let’s explore! https://github.com/arcosuc3m/clang-contracts Fork from clang-6 -build-level=(off|default|audit) http://fragata.arcos.inf.uc3m.es/#

Slide 151

Slide 151 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 151/168 Let’s explore! https://github.com/arcosuc3m/clang-contracts Fork from clang-6 http://fragata.arcos.inf.uc3m.es/# -build-level=(off|default|audit) -contract-violation-handler=function

Slide 152

Slide 152 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 152/168 When contracts are violated in C++20

Slide 153

Slide 153 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 153/168 When contracts are violated in C++20 A translation may be performed with one of the following violation continuation modes: off or on. A translation with violation continuation mode set to off terminates execution by invoking the function std/:terminate ([except.terminate]) after completing the execution of the violation handler. A translation with a violation continuation mode set to on continues execution after completing the execution of the violation handler. If no continuation mode is explicitly selected, the default continuation mode is off. [ Note: A continuation mode set to on provides the opportunity to install a logging handler to instrument a pre-existing code base and fix errors before enforcing checks. — end note ] http://eel.is/c/+draft/dcl.attr.contract#check-7

Slide 154

Slide 154 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 154/168 When contracts are violated in C++20 A translation may be performed with one of the following violation continuation modes: off or on. A translation with violation continuation mode set to off terminates execution by invoking the function std/:terminate ([except.terminate]) after completing the execution of the violation handler. A translation with a violation continuation mode set to on continues execution after completing the execution of the violation handler. If no continuation mode is explicitly selected, the default continuation mode is off. [ Note: A continuation mode set to on provides the opportunity to install a logging handler to instrument a pre-existing code base and fix errors before enforcing checks. — end note ] http://eel.is/c/+draft/dcl.attr.contract#check-7

Slide 155

Slide 155 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 155/168 When contracts are violated in C++20 A translation may be performed with one of the following violation continuation modes: off or on. A translation with violation continuation mode set to off terminates execution by invoking the function std/:terminate ([except.terminate]) after completing the execution of the violation handler. A translation with a violation continuation mode set to on continues execution after completing the execution of the violation handler. If no continuation mode is explicitly selected, the default continuation mode is off. [ Note: A continuation mode set to on provides the opportunity to install a logging handler to instrument a pre-existing code base and fix errors before enforcing checks. — end note ] http://eel.is/c/+draft/dcl.attr.contract#check-7

Slide 156

Slide 156 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 156/168 When contracts are violated in C++20 A translation may be performed with one of the following violation continuation modes: off or on. A translation with violation continuation mode set to off terminates execution by invoking the function std/:terminate ([except.terminate]) after completing the execution of the violation handler. A translation with a violation continuation mode set to on continues execution after completing the execution of the violation handler. If no continuation mode is explicitly selected, the default continuation mode is off. [ Note: A continuation mode set to on provides the opportunity to install a logging handler to instrument a pre-existing code base and fix errors before enforcing checks. — end note ] http://eel.is/c/+draft/dcl.attr.contract#check-7

Slide 157

Slide 157 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 157/168 When contracts are violated in C++20 A translation may be performed with one of the following violation continuation modes: off or on. A translation with violation continuation mode set to off terminates execution by invoking the function std/:terminate ([except.terminate]) after completing the execution of the violation handler. A translation with a violation continuation mode set to on continues execution after completing the execution of the violation handler. If no continuation mode is explicitly selected, the default continuation mode is off. [ Note: A continuation mode set to on provides the opportunity to install a logging handler to instrument a pre-existing code base and fix errors before enforcing checks. — end note ] http://eel.is/c/+draft/dcl.attr.contract#check-7 [ Example: void f(int x) [[expects: x > 0]]; void g() { f(0); // std /: terminate() after handler if // continuation mode is off; // proceeds after handler if // continuation mode is on /* //. // } — end example ]

Slide 158

Slide 158 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 158/168 Programming with Contracts in C++20 Björn Fahller

Slide 159

Slide 159 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 159/168 Summary ● Design by contract is a way to clarify the responsibility between a function implementation and its callers.

Slide 160

Slide 160 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 160/168 Summary ● Design by contract is a way to clarify the responsibility between a function implementation and its callers. ● Language support is coming in C++20

Slide 161

Slide 161 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 161/168 Summary ● Design by contract is a way to clarify the responsibility between a function implementation and its callers. ● Language support is coming in C++20 ● But it’s lacking class invariants

Slide 162

Slide 162 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 162/168 Summary ● Design by contract is a way to clarify the responsibility between a function implementation and its callers. ● Language support is coming in C++20 ● But it’s lacking class invariants ● and post conditions cannot refer to pre-call state.

Slide 163

Slide 163 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 163/168 Summary ● Design by contract is a way to clarify the responsibility between a function implementation and its callers. ● Language support is coming in C++20 ● But it’s lacking class invariants ● and post conditions cannot refer to pre-call state. ● Interesting gotchas: ● Modifying parameter values, and template specializations comes to mind.

Slide 164

Slide 164 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 164/168 Summary ● Design by contract is a way to clarify the responsibility between a function implementation and its callers. ● Language support is coming in C++20 ● But it’s lacking class invariants ● and post conditions cannot refer to pre-call state. ● Interesting gotchas: ● Modifying parameter values, and template specializations comes to mind. ● Contracts can be used by static analysis tools and the optimizer.

Slide 165

Slide 165 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 165/168 Summary ● Design by contract is a way to clarify the responsibility between a function implementation and its callers. ● Language support is coming in C++20 ● But it’s lacking class invariants ● and post conditions cannot refer to pre-call state. ● Interesting gotchas: ● Modifying parameter values, and template specializations comes to mind. ● Contracts can be used by static analysis tools and the optimizer. ● Configurable levels of contracts, e.g. full in debug builds, only cheap ones in release.

Slide 166

Slide 166 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 166/168 Summary ● Design by contract is a way to clarify the responsibility between a function implementation and its callers. ● Language support is coming in C++20 ● But it’s lacking class invariants ● and post conditions cannot refer to pre-call state. ● Interesting gotchas: ● Modifying parameter values, and template specializations comes to mind. ● Contracts can be used by static analysis tools and the optimizer. ● Configurable levels of contracts, e.g. full in debug builds, only cheap ones in release. ● Prefer to express semantics using the type system, if you can.

Slide 167

Slide 167 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 167/168 Summary ● Design by contract is a way to clarify the responsibility between a function implementation and its callers. ● Language support is coming in C++20 ● But it’s lacking class invariants ● and post conditions cannot refer to pre-call state. ● Interesting gotchas: ● Modifying parameter values, and template specializations comes to mind. ● Contracts can be used by static analysis tools and the optimizer. ● Configurable levels of contracts, e.g. full in debug builds, only cheap ones in release. ● Prefer to express semantics using the type system, if you can. Play with it! https://github.com/arcosuc3m/clang-contracts Fork from clang-6 http://fragata.arcos.inf.uc3m.es/#

Slide 168

Slide 168 text

Programming with Contracts in C++20 – ACCU 2019 © Björn Fahller @bjorn_fahller 168/168 Björn Fahller Programming with Contracts in C++20 [email protected] @bjorn_fahller @rollbear