From 37f9c9335bd827dd833580cfb215698e15efa77b Mon Sep 17 00:00:00 2001 From: Francesco Giacomini <giaco at cnaf dot infn dot it> Date: Thu, 19 Oct 2017 16:30:38 +0200 Subject: [PATCH] frames.tex --- frames.tex | 779 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 512 insertions(+), 267 deletions(-) diff --git a/frames.tex b/frames.tex index 01c3bee..1bb64f1 100644 --- a/frames.tex +++ b/frames.tex @@ -1,5 +1,5 @@ -%\includeonlyframes{current} +\includeonlyframes{current} \begin{frame} \tikz [remember picture,overlay] @@ -286,7 +286,7 @@ bool less(int n, int m) \{ return n < m; \}\end{codeblock} \begin{codeblock} \uncover<1->{std::array<int,3> a = \{123, 456, 789\};} \uncover<2->{\alert<2>{auto first = a.begin();} // or std::begin(a)} -\uncover<3->{\alert<3>{auto \alt<14>{\alert{const }}{}last = a.end();}\alt<14>{}{ } // or std::end(a)} +\uncover<3->{\alert<3>{auto \only<14->{\alert{const }}last = a.end();}\only<-13>{ } // or std::end(a)} \uncover<4->{while (\alert<4,7,10,13>{first != last}) \{ ... \alert<5,8,11>{*first} ...; \alert<6,9,12>{++first}; @@ -380,7 +380,7 @@ find(Iterator first, Iterator last, const T\& value) \begin{itemize} \item Examples \begin{codeblock} -std::vector<int> v = { 2, 5, 4, 0, 1 }; +std::vector<int> v = \{ 2, 5, 4, 0, 1 \}; // sort the first half of the vector in ascending order std::sort(std::begin(v), std::begin(v) + v.size() / 2); @@ -595,8 +595,8 @@ accumulate(\ldots, \uncover<2->{class SomeUniqueName \{ \uncover<5->{int v\_;} public: - explicit SomeUniqueName(\uncover<5->{int v}) - \uncover<5->{: v\_\{v\}} \{\} + \uncover<5->{explicit SomeUniqueName(int v) + : v\_\{v\} \{\}} \alt<-7>{auto}{\alert<8>{int }} operator()\uncover<3->{(int i) \{ return i + v\uncover<5->{\_}; \}} \};} @@ -1171,6 +1171,513 @@ auto s = std::shared\_ptr<FILE>\{ \end{columns} \end{frame} +\begin{frame} + \begin{itemize} + \item Try the code snippets + \item C++ and Memory $\rightarrow$ Pointers + \item Adapt the previous exercises to use smart pointers + \item Starting from \code{dir.cpp}, write code to: + \begin{itemize} + \item create a smart pointer managing a \code{DIR} resource obtained with + the \code{opendir} function call + \item associate a deleter to that smart pointer + \item implement a function to read the names of the files in that directory + \item check if the deleter is called at the right moment + \item hide the creation of the smart pointer behind a factory function + \item populate a vector of FILEs, properly wrapped in a smart pointer, + obtained opening the regular files in that directory + \item \ldots + \end{itemize} + \end{itemize} +\end{frame} + +\section{Move semantics} + +\begin{frame}[fragile,label=current]{Copy vs move} + + \begin{columns} + \begin{column}{.45\textwidth} + + \begin{codeblock}{\tiny +class String \{ + char* s\_; + \ldots +\};}\end{codeblock} + + \begin{codeblock}<1->{\tiny +String s1\{"Hi!"\}; +\uncover<2->{String s2\{s1\};}}\end{codeblock} + + \uncover<3->{\small + \begin{itemize} + \item Both \code{s1} and \code{s2} exist at the end + \item The ``deep'' copy is needed + \end{itemize} + } + + \begin{codeblock}<4->{\tiny +String get\_string() \{ return "Hey"; \} +String \alert<6>{s3}\{\alert<5>{get\_string()}\}\alert<7>{;}}\end{codeblock} + + \uncover<8->{\small + \begin{itemize} + \item Only \code{s3} exists at the end + \item The ``deep'' copy is a waste + \end{itemize} + } + \end{column} + + \begin{column}{.55\textwidth} + \newcommand*{\stackx}{0.} + \newcommand*{\heapx}{3.0} + + \begin{tikzpicture} + [anchor=south west] + \node at (\stackx,0) [ + rectangle, + minimum width=2cm, + minimum height=7cm, + draw=black, + label={90:{\scriptsize stack}} + ] {}; + \node at (\heapx,0) [ + rectangle, + minimum width=2cm, + minimum height=7cm, + draw=black, + label={90:{\scriptsize heap}} + ] {}; + \node at (\heapx-0.1,4.9) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=0.7cm, + ] {}; + \node at (\heapx,5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white + ] {\scriptsize\tt Hi!\char`\\0}; + \node at (\heapx,5) [ + rectangle, + minimum width=.5cm, + minimum height=.5cm, + draw=black, + densely dotted, + label={270:{\scriptsize\tt 0x4abc}} + ] {}; + \node at (\stackx-0.1,4.9) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=.7cm, + label={180:{\scriptsize\tt s1}}, + ] {}; + \node at (\stackx,5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white, + ] {\scriptsize\tt 0x4abc}; + \visible<2->{ + \node at (\heapx-0.1,3.9) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=0.7cm, + ] {}; + \node at (\heapx,4) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white + ] {\scriptsize\tt Hi!\char`\\0}; + \node at (\heapx,4) [ + rectangle, + minimum width=.5cm, + minimum height=.5cm, + draw=black, + densely dotted, + label={270:{\scriptsize\tt 0x4ab0}} + ] (r2) {}; + \node at (\stackx-0.1,3.9) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=.7cm, + label={180:{\scriptsize\tt s2}}, + ] {}; + \node at (\stackx,4) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white, + ] (h2) {\scriptsize\tt 0x4ab0}; + %\draw[arrow] (h2) -- (r2); + } + \visible<6->{ + \node at (\heapx-0.1,2.4) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=0.7cm, + ] {}; + \node at (\heapx,2.5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white + ] {\scriptsize\tt Hey\char`\\0}; + \node at (\heapx,2.5) [ + rectangle, + minimum width=.5cm, + minimum height=.5cm, + draw=black, + densely dotted, + label={270:{\scriptsize\tt 0x4aac}} + ] {}; + \node at (\stackx-0.1,2.4) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=.7cm, + label={180:{\scriptsize\tt s3}}, + ] {}; + \node at (\stackx,2.5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white, + ] {\scriptsize\tt 0x4aac}; + } + \visible<5-6>{ + \node at (\heapx-0.1,1.4) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=0.7cm, + ] {}; + \node at (\heapx,1.5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white + ] {\scriptsize\tt Hey\char`\\0}; + \node at (\heapx,1.5) [ + rectangle, + minimum width=.5cm, + minimum height=.5cm, + draw=black, + densely dotted, + label={270:{\scriptsize\tt 0x4aa0}} + ] {}; + \node at (\stackx-0.1,1.4) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=.7cm, + ] {}; + \node at (\stackx,1.5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white, + ] {\scriptsize\tt 0x4aa0}; + } + \end{tikzpicture} + \end{column} + \end{columns} + +\end{frame} + +\begin{frame}[fragile,label=current]{Copy vs move \insertcontinuationtext} + + \begin{columns} + \begin{column}{.45\textwidth} + + \begin{codeblock}{\tiny +\uncover<1->{class String \{ + char* s\_; + public: + String(char const* s) \{ + size\_t size = strlen(s) + 1; + s\_ = new char[size]; + memcpy(s\_, s, size); + \} + ~String() \{ delete [] s\_; \}} +\uncover<2->{ // \alert<2>{copy} + String(String const& other) \{ + size\_t size = strlen(other.s\_) + 1; + s\_ = new char[size]; + memcpy(s\_, other.s\_, size); + \}} +\uncover<4->{ // \alert<4-5>{move} + String(\alert<7>{???} tmp): s\_(tmp.s\_) \{ +\uncover<5->{ tmp.s\_ = nullptr;} + \}} +\uncover<1->{ \ldots +\}; + +String s1\{"Hi!"\};} +\uncover<2->{String s2\{s1\};} +\uncover<3->{String \alert<4>{s3}\{\alert<3>{get\_string()}\}\alert<6>{;}} +}\end{codeblock} + + \end{column} + + \begin{column}{.55\textwidth} + \newcommand*{\stackx}{0.} + \newcommand*{\heapx}{3.0} + + \begin{tikzpicture} + [anchor=south west] + \node at (\stackx,0) [ + rectangle, + minimum width=2cm, + minimum height=7cm, + draw=black, + label={90:{\scriptsize stack}} + ] {}; + \node at (\heapx,0) [ + rectangle, + minimum width=2cm, + minimum height=7cm, + draw=black, + label={90:{\scriptsize heap}} + ] {}; + \node at (\heapx-0.1,4.9) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=0.7cm, + ] {}; + \node at (\heapx,5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white + ] {\scriptsize\tt Hi!\char`\\0}; + \node at (\heapx,5) [ + rectangle, + minimum width=.5cm, + minimum height=.5cm, + draw=black, + densely dotted, + label={270:{\scriptsize\tt 0x4abc}} + ] {}; + \node at (\stackx-0.1,4.9) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=.7cm, + label={180:{\scriptsize\tt s1}}, + ] {}; + \node at (\stackx,5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white, + ] {\scriptsize\tt 0x4abc}; + \visible<2->{ + \node at (\heapx-0.1,3.9) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=0.7cm, + ] {}; + \node at (\heapx,4) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white + ] {\scriptsize\tt Hi!\char`\\0}; + \node at (\heapx,4) [ + rectangle, + minimum width=.5cm, + minimum height=.5cm, + draw=black, + densely dotted, + label={270:{\scriptsize\tt 0x4ab0}} + ] (r2) {}; + \node at (\stackx-0.1,3.9) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=.7cm, + label={180:{\scriptsize\tt s2}}, + ] {}; + \node at (\stackx,4) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white, + ] (h2) {\scriptsize\tt 0x4ab0}; + %\draw[arrow] (h2) -- (r2); + } + \visible<4->{ + \node at (\stackx-0.1,2.4) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=.7cm, + label={180:{\scriptsize\tt s3}}, + ] {}; + \node at (\stackx,2.5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white, + ] {\scriptsize\tt \alert<4>{0x4aa0}}; + } + \visible<3->{ + \node at (\heapx-0.1,1.4) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=0.7cm, + ] {}; + \node at (\heapx,1.5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white + ] {\scriptsize\tt Hey\char`\\0}; + \node at (\heapx,1.5) [ + rectangle, + minimum width=.5cm, + minimum height=.5cm, + draw=black, + densely dotted, + label={270:{\scriptsize\tt 0x4aa0}} + ] {}; + } + \visible<3-5>{ + \node at (\stackx-0.1,1.4) [ + rectangle, + fill=green!10!white, + draw=black!40, + minimum width=2.2cm, + minimum height=.7cm, + ] {}; + \node at (\stackx,1.5) [ + rectangle, + minimum width=2cm, + minimum height=.5cm, + draw=black, + fill=green!30!white, + ] {\scriptsize\tt \alt<3-4>{\alert<4>{0x4aa0}}{\code{\alert<5>{nullptr}}}}; + } + \end{tikzpicture} + \end{column} + \end{columns} +\end{frame} + +\begin{frame}[label=current]{lvalues vs rvalues} + \begin{itemize} + \item The taxonomy of values in C++ is complex + \begin{itemize} + \item glvalue, prvalue, xvalue, lvalue, rvalue + \end{itemize} + \item We can assume + \begin{description} + \item [lvalue] A named object + \begin{itemize} + \item for which you can take the address + \item \alert{l} stands for ``left'' because it used to represent the + \alert{l}eft-hand side of an assignment + \end{itemize} + \item [rvalue] An unnamed (temporary) object + \begin{itemize} + \item for which you can't take the address + \item \alert{r} stands for ``right'' because it used to represent the + \alert{r}ight-hand side of an assignment + \end{itemize} + \end{description} + \end{itemize} +\end{frame} + +\begin{frame}[fragile,label=current]{Rvalue reference} + \begin{itemize} + \item A \texttt{T\&\&} is an rvalue reference + \begin{itemize} + \item introduced in C++11 + \end{itemize} + \item It binds to rvalues but not to lvalues + \end{itemize} + + \begin{codeblock}<2->{\tiny +class Thing; +Thing make\_thing(); + +Thing t; + +\uncover<3->{Thing & r = t;}\uncover<4->{ // ok} +\uncover<5->{Thing && r = t;}\uncover<6->{ // error} +\uncover<7->{Thing & r = make\_thing();}\uncover<8->{ // error} +\uncover<9->{Thing && r = make\_thing();}\uncover<10->{ // ok} +\uncover<11->{Thing const& r = make\_thing();}\uncover<12->{ // ok (!)} +\uncover<13->{Thing const&& r = make\_thing();}\uncover<14->{ // ok, but what for?}}\end{codeblock} + + \begin{codeblock}<15->{\tiny +class String \{ + // move constructor + String(String\alert<15>{&&} tmp) : s\_(tmp.s\_) \{ + tmp.s\_ = nullptr; + \} +\}; + +String s2\{s1\}; // call String::String(String const&) +String s3\{get\_string()\}; // call String::String(String&&)}\end{codeblock} + +\end{frame} + +\begin{frame}[fragile,label=current]{Rvalue reference \insertcontinuationtext} + \begin{itemize} + \item Any function can accept rvalue references + \begin{codeblock} +void foo(String&&); + +foo(get\_string()); +foo(String\{"hello"\});\end{codeblock} + \item lvalues can be explicitly transformed into rvalues + \begin{codeblock} +String s; +foo(s); // error +foo(std::move(s)); // ok, I don't care any more about s +s.size(); // dangerous\end{codeblock} + \end{itemize} +\end{frame} + + \begin{frame}[fragile]{Smart pointers \insertcontinuationtext} \begin{columns}[c] @@ -2099,241 +2606,6 @@ Handle h1\{10\}, h2\{20\}; arrow/.style={->} } -\begin{frame}[fragile]{Copy vs move} - - \begin{columns} - \begin{column}{.45\textwidth} - - \begin{codeblock}<1-> -Handle h1\{123\}; -\uncover<2->{Handle h2\{h1\};}\end{codeblock} - - \uncover<3->{\small - \begin{itemize} - \item Both \texttt{h1} and \texttt{h2} exist at the end - \item The ``deep'' copy is needed - \end{itemize} - } - - \begin{codeblock}<4-> -Handle make\_holder(); -Handle \alert<6>{h3}\{\alert<5>{make\_holder()}\}\alert<7>{;}\end{codeblock} - - \uncover<8->{\small - \begin{itemize} - \item Only \texttt{h3} exists at the end - \item The ``deep'' copy is a waste - \item Could reuse the ``guts'' of the temporary - \end{itemize} - } - \end{column} - - \begin{column}{.55\textwidth} - \newcommand*{\stackx}{0.} - \newcommand*{\heapx}{3.0} - - \begin{tikzpicture} - [anchor=south west] - \node at (\stackx,0) [ - rectangle, - minimum width=2cm, - minimum height=7cm, - draw=black, - label={90:{\scriptsize stack}} - ] {}; - \node at (\heapx,0) [ - rectangle, - minimum width=2cm, - minimum height=7cm, - draw=black, - label={90:{\scriptsize heap}} - ] {}; - \node at (\heapx-0.1,4.9) [ - rectangle, - fill=green!10!white, - draw=black!40, - minimum width=2.2cm, - minimum height=0.7cm, - ] {}; - \node at (\heapx,5) [ - rectangle, - minimum width=2cm, - minimum height=.5cm, - draw=black, - fill=green!30!white - ] {\scriptsize\tt 123}; - \node at (\heapx,5) [ - rectangle, - minimum width=.5cm, - minimum height=.5cm, - draw=black, - densely dotted, - label={270:{\scriptsize\tt 0x4abc}} - ] {}; - \node at (\stackx-0.1,4.9) [ - rectangle, - fill=green!10!white, - draw=black!40, - minimum width=2.2cm, - minimum height=.7cm, - label={180:{\scriptsize\tt h1}}, - ] {}; - \node at (\stackx,5) [ - rectangle, - minimum width=2cm, - minimum height=.5cm, - draw=black, - fill=green!30!white, - ] {\scriptsize\tt 0x4abc}; - \visible<2->{ - \node at (\heapx-0.1,3.9) [ - rectangle, - fill=green!10!white, - draw=black!40, - minimum width=2.2cm, - minimum height=0.7cm, - ] {}; - \node at (\heapx,4) [ - rectangle, - minimum width=2cm, - minimum height=.5cm, - draw=black, - fill=green!30!white - ] {\scriptsize\tt 123}; - \node at (\heapx,4) [ - rectangle, - minimum width=.5cm, - minimum height=.5cm, - draw=black, - densely dotted, - label={270:{\scriptsize\tt 0x4ab0}} - ] (r2) {}; - \node at (\stackx-0.1,3.9) [ - rectangle, - fill=green!10!white, - draw=black!40, - minimum width=2.2cm, - minimum height=.7cm, - label={180:{\scriptsize\tt h2}}, - ] {}; - \node at (\stackx,4) [ - rectangle, - minimum width=2cm, - minimum height=.5cm, - draw=black, - fill=green!30!white, - ] (h2) {\scriptsize\tt 0x4ab0}; - %\draw[arrow] (h2) -- (r2); - } - \visible<6->{ - \node at (\heapx-0.1,2.4) [ - rectangle, - fill=green!10!white, - draw=black!40, - minimum width=2.2cm, - minimum height=0.7cm, - ] {}; - \node at (\heapx,2.5) [ - rectangle, - minimum width=2cm, - minimum height=.5cm, - draw=black, - fill=green!30!white - ] {\scriptsize\tt 456}; - \node at (\heapx,2.5) [ - rectangle, - minimum width=.5cm, - minimum height=.5cm, - draw=black, - densely dotted, - label={270:{\scriptsize\tt 0x4aac}} - ] {}; - \node at (\stackx-0.1,2.4) [ - rectangle, - fill=green!10!white, - draw=black!40, - minimum width=2.2cm, - minimum height=.7cm, - label={180:{\scriptsize\tt h3}}, - ] {}; - \node at (\stackx,2.5) [ - rectangle, - minimum width=2cm, - minimum height=.5cm, - draw=black, - fill=green!30!white, - ] {\scriptsize\tt 0x4aac}; - } - \visible<5-6>{ - \node at (\heapx-0.1,1.4) [ - rectangle, - fill=green!10!white, - draw=black!40, - minimum width=2.2cm, - minimum height=0.7cm, - ] {}; - \node at (\heapx,1.5) [ - rectangle, - minimum width=2cm, - minimum height=.5cm, - draw=black, - fill=green!30!white - ] {\scriptsize\tt 456}; - \node at (\heapx,1.5) [ - rectangle, - minimum width=.5cm, - minimum height=.5cm, - draw=black, - densely dotted, - label={270:{\scriptsize\tt 0x4aa0}} - ] {}; - \node at (\stackx-0.1,1.4) [ - rectangle, - fill=green!10!white, - draw=black!40, - minimum width=2.2cm, - minimum height=.7cm, - ] {}; - \node at (\stackx,1.5) [ - rectangle, - minimum width=2cm, - minimum height=.5cm, - draw=black, - fill=green!30!white, - ] {\scriptsize\tt 0x4aa0}; - } - \end{tikzpicture} - \end{column} - \end{columns} - -\end{frame} - -\section{Move semantics} - -\begin{frame}{lvalues vs rvalues} - \begin{itemize} - \item The taxonomy of values in C++ is complex - \begin{itemize} - \item glvalue, prvalue, xvalue, lvalue, rvalue - \end{itemize} - \item We can assume - \begin{description} - \item [lvalue] A named object - \begin{itemize} - \item for which you can take the address - \item \alert{l} stands for ``left'' because it used to represent the - \alert{l}eft-hand side of an assignment - \end{itemize} - \item [rvalue] An unnamed (temporary) object - \begin{itemize} - \item for which you can't take the address - \item \alert{r} stands for ``right'' because it used to represent the - \alert{r}ight-hand side of an assignment - \end{itemize} - \end{description} - \end{itemize} -\end{frame} - \begin{frame}[fragile]{Move constructor} \begin{columns} @@ -2447,33 +2719,6 @@ Handle \alert<3-5>{h\{}\alert<2>{make\_holder()}\alert<3-5>{\}}\alert<6>{;}\end{ \end{frame} -\begin{frame}[fragile]{Rvalue reference} - \begin{itemize} - \item A \texttt{T\&\&} is an rvalue reference - \item It binds to rvalues but not to lvalues - \end{itemize} - - \begin{codeblock}<2->{ -class Thing; -Thing make\_thing(); - -Thing t; - -\uncover<3->{Thing & r = t;}\uncover<4->{ // ok} -\uncover<5->{Thing && r = t;}\uncover<6->{ // error} -\uncover<7->{Thing & r = make\_thing();}\uncover<8->{ // error} -\uncover<9->{Thing && r = make\_thing();}\uncover<10->{ // ok} -\uncover<11->{Thing const& r = make\_thing();}\uncover<12->{ // ok (!)} -\uncover<13->{Thing const&& r = make\_thing();}\uncover<14->{ // ok, but what for?}}\end{codeblock} - - \uncover<15->{ - \begin{itemize} - \item A reference extends the lifetime of a temporary object until the end of the scope - \end{itemize} - } - -\end{frame} - \begin{frame}[fragile]{Move assignment} \begin{columns} -- GitLab