Skip to content

Commit 1b2651c

Browse files
Add slides on initialization
These include scalar, class type, default, value and aggregate initialization. Aggregate initialization is removed from the constructor discussions. Fixes: hsf-training#146, hsf-training#155 Co-authored-by: Stephan Hageboeck <stephan.hageboeck@cern.ch>
1 parent 31290ab commit 1b2651c

File tree

3 files changed

+229
-52
lines changed

3 files changed

+229
-52
lines changed

talk/morelanguage/initialization.tex

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
\subsection[Init]{Initialization}
2+
3+
\begin{frame}[fragile]
4+
\frametitle{Initialization}
5+
\begin{block}{Initialization}
6+
\begin{itemize}
7+
\item \href{https://imgur.com/3wlxtI0}{Obligatory meme}
8+
\pause
9+
\item And the following were even missing:
10+
\begin{itemize}
11+
\item ordered, unordered, and partially ordered initialization
12+
\item direct-non-list-initialization
13+
\item non-vacuous initialization
14+
\item See \href{https://twitter.com/timur_audio/status/1004017362381795329}{this tweet}
15+
\end{itemize}
16+
\item Most of this is for language lawyers
17+
\item In the following we will discuss some practical implications
18+
\end{itemize}
19+
\end{block}
20+
\end{frame}
21+
22+
\begin{frame}[fragile]
23+
\frametitle{Initialization}
24+
\begin{block}{Initializing scalars}
25+
\begin{cppcode}
26+
int i(42); // direct initialization
27+
int i{42}; // direct list initialization (C++11)
28+
int i = 42; // copy initialization
29+
int i = {42}; // copy list initialization (C++11)
30+
\end{cppcode}
31+
\begin{itemize}
32+
\item All of the above have the same effect: \mintinline{cpp}{i == 42}
33+
\end{itemize}
34+
\end{block}
35+
\begin{block}{Narrowing conversions}
36+
\begin{cppcode}
37+
int i(42.3); // i == 42
38+
int i{42.3}; // compilation error
39+
int i = 42.3; // i == 42
40+
int i = {42.3}; // compilation error
41+
\end{cppcode}
42+
\begin{itemize}
43+
\item Braced initialization prevents narrowing conversions
44+
\end{itemize}
45+
\end{block}
46+
\end{frame}
47+
48+
\begin{frame}[fragile,shrink=10]
49+
\frametitle{Initialization}
50+
\begin{block}{Initializing class types with constructors}
51+
\begin{cppcode}
52+
struct C {
53+
C(int i);
54+
C(int i, int j);
55+
};
56+
57+
C c(42); // calls C(42)
58+
C c{42}; // same
59+
C c = 42; // calls C(42) in C++17, before C(C(42))
60+
C c = {42}; // same
61+
62+
C c(1, 2); // calls C(1, 2)
63+
C c{1, 2}; // calls C(1, 2)
64+
C c = (1, 2); // calls C(2), comma operator
65+
C c = {1, 2}; // calls C(1, 2) in C++17, before C(C(1, 2))
66+
67+
C c(1.1, 2.2); // calls C(1, 2)
68+
C c{1.1, 2.2}; // compilation error
69+
\end{cppcode}
70+
\end{block}
71+
\end{frame}
72+
73+
\begin{frame}[fragile,shrink=10]
74+
\frametitle{Initialization}
75+
\begin{block}{std::initializer\_list}
76+
\begin{cppcode}
77+
struct C {
78+
C(int i, int j);
79+
C(std::initializer_list<int> l);
80+
};
81+
82+
C c(1, 2); // calls C(1, 2)
83+
C c{1, 2}; // calls C(std::initializer_list<int>{1, 2})
84+
C c = (1, 2); // calls C(2), comma operator, error
85+
C c = {1, 2}; // calls C(std::initializer_list<int>{1, 2})
86+
\end{cppcode}
87+
\begin{itemize}
88+
\item A constructor with a \mintinline{cpp}{std::initializer_list} parameter takes precedence over other overloads.
89+
\end{itemize}
90+
\end{block}
91+
\begin{alertblock}{Beware}
92+
\begin{cppcode}
93+
std::vector<int> v1(4, 5); // {5, 5, 5, 5}
94+
std::vector<int> v2{4, 5}; // {4, 5}
95+
\end{cppcode}
96+
\end{alertblock}
97+
\end{frame}
98+
99+
\begin{frame}[fragile]
100+
\frametitle{Initialization}
101+
\begin{block}{Type deduction}
102+
\begin{cppcode}
103+
auto i(42); // int
104+
auto i{42}; // C++11: std::initializer_list<int>
105+
// since C++14: int
106+
auto i = 42; // int
107+
auto i = {42}; // std::initializer_list<int>
108+
\end{cppcode}
109+
\end{block}
110+
\end{frame}
111+
112+
\begin{frame}[fragile]
113+
\frametitlecpp[11]{Initialization}
114+
\begin{block}{Default initialization}
115+
\begin{cppcode*}{linenos=false}
116+
T t;
117+
\end{cppcode*}
118+
\begin{itemize}
119+
\item If \mintinline{cpp}{T} has a default constructor (including compiler generated), calls it
120+
\item Otherwise \mintinline{cpp}{t} is left uninitialized (undefined value)
121+
\item If \mintinline{cpp}{T} is an array, default initializes all members
122+
\end{itemize}
123+
\end{block}
124+
\end{frame}
125+
126+
\begin{frame}[fragile]
127+
\frametitlecpp[11]{Initialization}
128+
\begin{block}{Value initialization}
129+
\begin{cppcode}
130+
T t{}; // value initialization
131+
T t = {}; // same
132+
f(T()); // passes value-initialized temporary
133+
f(T{}); // same
134+
T t(); // function declaration
135+
\end{cppcode}
136+
\begin{itemize}
137+
\item Basically zero-initializes \mintinline{cpp}{t} (or the temporary), unless \mintinline{cpp}{T} has a user defined constructor
138+
\item Details on \href{https://en.cppreference.com/w/cpp/language/value_initialization}{cppreference}
139+
\end{itemize}
140+
\end{block}
141+
\end{frame}
142+
143+
\begin{frame}[fragile,shrink=10]
144+
\frametitlecpp[11]{Initialization}
145+
\begin{block}{Aggregate initialization}
146+
\begin{cppcode}
147+
struct S { int i; double d; };
148+
149+
S s{1, 2.3}; // s.i == 1, s.d == 2.3
150+
S s = {1, 2.3}; // same
151+
S s{.i = 1, .d = 2.3} // same, designated init. (C++20)
152+
S s = {.i = 1, .d = 2.3} // same
153+
S s{1}; // s.i == 1, s.d == 0.0
154+
S s = {1}; // same
155+
S s{.i = 1} // same (C++20)
156+
S s = {.i = 1} // same (C++20)
157+
S s{}; // value init, s.i == 0, s.d == 0.0
158+
S s; // default init, undefined values
159+
\end{cppcode}
160+
\begin{itemize}
161+
\item An aggregate is a class with no constructors, only public base classes (\cpp17) and members, no virtual functions, no default member initializers (until \cpp14)
162+
\item Details on \href{https://en.cppreference.com/w/cpp/language/aggregate_initialization}{cppreference}
163+
\end{itemize}
164+
\end{block}
165+
\end{frame}
166+
167+
\begin{frame}[fragile]
168+
\frametitlecpp[11]{Initialization}
169+
\begin{exampleblock}{Best practices}
170+
\begin{itemize}
171+
\item In generic code, for a generic type \mintinline{cpp}{T}:
172+
\begin{itemize}
173+
\item \mintinline{cpp}{T t;} performs the minimally necessary initialization
174+
\item \mintinline{cpp}{T t{};} performs full and deterministic initialization
175+
\end{itemize}
176+
\item Prefer \mintinline{cpp}{T t{};} over \mintinline{cpp}{T t; memset(&t, 0, sizeof(t));}
177+
\item Prefer braces over parentheses to avoid accidental narrowing conversions
178+
\begin{itemize}
179+
\item Unless \mintinline{cpp}{T} has a \mintinline{cpp}{std::initializer_list} constructor that you do not want to call!
180+
\item Be wary of \mintinline{cpp}{std::vector}!
181+
\end{itemize}
182+
\item The STL value initializes when creating new user objects
183+
\begin{itemize}
184+
\item E.g. \mintinline{cpp}{vec.resize(vec.size() + 10);}
185+
\end{itemize}
186+
\item Aggregates are very flexible. If your class does not need special initialization, make it an aggregate
187+
\end{itemize}
188+
\end{exampleblock}
189+
\end{frame}
190+
191+
\begin{frame}[fragile]
192+
\frametitle{Initialization}
193+
\begin{block}{Further resources}
194+
\begin{itemize}
195+
\item \href{https://www.youtube.com/watch?v=7DTlWPgX6zs}{CppCon 2018: Nicolai Josuttis “The Nightmare of Initialization in C++”}
196+
\item \href{https://www.youtube.com/watch?v=ZfP4VAK21zc}{Initialization in modern C++ - Timur Doumler - Meeting C++ 2018}
197+
\end{itemize}
198+
\end{block}
199+
\end{frame}

talk/morelanguage/morelanguage.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
\input{morelanguage/morestl}
1111
\input{morelanguage/lambda}
1212
\input{morelanguage/raii}
13+
\input{morelanguage/initialization}

talk/objectorientation/constructors.tex

Lines changed: 29 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -259,65 +259,42 @@
259259
\begin{frame}[fragile]
260260
\frametitlecpp[11]{Calling constructors}
261261
\begin{block}{After object declaration, arguments within \{\}}
262-
\begin{multicols}{2}
263-
\begin{cppcode*}{gobble=4}
264-
struct A {
265-
int a;
266-
float b;
267-
A();
268-
A(int);
269-
A(int, int);
270-
};
271-
\end{cppcode*}
272-
\columnbreak
273-
\begin{cppcode*}{gobble=4,firstnumber=8}
274-
struct B {
275-
int a;
276-
float b;
277-
// no constructor
278-
};
279-
\end{cppcode*}
280-
\end{multicols}
281-
\begin{cppcode*}{gobble=2, firstnumber=13}
282-
A a{1,2}; // A::A(int, int)
283-
A a{1}; // A::A(int)
284-
A a{}; // A::A()
285-
A a; // A::A()
286-
A a = {1,2}; // A::A(int, int)
287-
B b = {1, 2.3}; // aggregate initialization
262+
\begin{cppcode*}{gobble=2}
263+
struct A {
264+
int a;
265+
float b;
266+
A();
267+
A(int);
268+
A(int, int);
269+
};
270+
271+
A a{1,2}; // A::A(int, int)
272+
A a{1}; // A::A(int)
273+
A a{}; // A::A()
274+
A a; // A::A()
275+
A a = {1,2}; // A::A(int, int)
288276
\end{cppcode*}
289277
\end{block}
290278
\end{frame}
291279

292280
\begin{frame}[fragile]
293281
\frametitlecpp[98]{Calling constructors the old way}
294282
\begin{block}{Arguments are given within (), aka \cpp98 nightmare}
295-
\begin{multicols}{2}
296-
\begin{cppcode*}{gobble=4}
297-
struct A {
298-
int a;
299-
float b;
300-
A();
301-
A(int);
302-
A(int, int);
303-
};
304-
\end{cppcode*}
305-
\columnbreak
306-
\begin{cppcode*}{gobble=4,firstnumber=8}
307-
struct B {
308-
int a;
309-
float b;
310-
// no constructor
311-
};
312-
\end{cppcode*}
313-
\end{multicols}
314-
\begin{cppcode*}{gobble=2, firstnumber=13}
315-
A a(1,2); // A::A(int, int)
316-
A a(1); // A::A(int)
317-
A a(); // declaration of a function !
318-
A a; // A::A()
319-
A a = {1,2}; // not allowed
320-
B b = {1, 2.3}; // OK
283+
\begin{cppcode*}{gobble=2}
284+
struct A {
285+
int a;
286+
float b;
287+
A();
288+
A(int);
289+
A(int, int);
290+
};
291+
292+
A a(1,2); // A::A(int, int)
293+
A a(1); // A::A(int)
294+
A a(); // declaration of a function !
295+
A a; // A::A()
296+
A a = (1,2); // A::A(int), comma operator !
297+
A a = {1,2}; // not allowed
321298
\end{cppcode*}
322299
\end{block}
323300
\end{frame}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy