Download as pdf or txt
Download as pdf or txt
You are on page 1of 69

C Initialization Story A Guide Through

All Initialization Options and Related C


Areas Bart■omiej Filipek
Visit to download the full and correct content document:
https://ebookmeta.com/product/c-initialization-story-a-guide-through-all-initialization-o
ptions-and-related-c-areas-bartlomiej-filipek/
More products digital (pdf, epub, mobi) instant
download maybe you interests ...

Options, Futures, and Other Derivatives: Eleventh


Edition [Global] John C. Hull

https://ebookmeta.com/product/options-futures-and-other-
derivatives-eleventh-edition-global-john-c-hull/

Options The Essential Guide for Getting Started in


Derivatives Trading Tenth Edition Michael C Thomsett

https://ebookmeta.com/product/options-the-essential-guide-for-
getting-started-in-derivatives-trading-tenth-edition-michael-c-
thomsett/

Data Structures Through C++ (4th Ed.) Yashavant


Kanetkar

https://ebookmeta.com/product/data-structures-through-c-4th-ed-
yashavant-kanetkar/

Head First C#: A Learner's Guide to Real-World


Programming with C# and .NET Core 4th Edition Stellman

https://ebookmeta.com/product/head-first-c-a-learners-guide-to-
real-world-programming-with-c-and-net-core-4th-edition-stellman/
All In Roulette 2 1st Edition C B Alice

https://ebookmeta.com/product/all-in-roulette-2-1st-edition-c-b-
alice/

Options and Derivatives Programming in C++23:


Algorithms and Programming Techniques for the Financial
Industry, 3rd Edition Carlos Oliveira

https://ebookmeta.com/product/options-and-derivatives-
programming-in-c23-algorithms-and-programming-techniques-for-the-
financial-industry-3rd-edition-carlos-oliveira/

Data Structures and Algorithms Implementation through C


1st Edition Dr. Brijesh Bakariya.

https://ebookmeta.com/product/data-structures-and-algorithms-
implementation-through-c-1st-edition-dr-brijesh-bakariya/

Data Structures Through C 3rd Ed 1st Edition Yashavant


Kanetkar

https://ebookmeta.com/product/data-structures-through-c-3rd-
ed-1st-edition-yashavant-kanetkar/

Head First C A Learner s Guide to Real World


Programming with C and NET Core 4th Edition Andrew
Stellman

https://ebookmeta.com/product/head-first-c-a-learner-s-guide-to-
real-world-programming-with-c-and-net-core-4th-edition-andrew-
stellman/
C++ Initialization Story
A Guide Through All Initialization Options and Related
C++ Areas

Bartłomiej Filipek
This book is for sale at http://leanpub.com/cppinitbook

This version was published on 2022-12-23

This is a Leanpub book. Leanpub empowers authors and publishers with the Lean
Publishing process. Lean Publishing is the act of publishing an in-progress ebook using
lightweight tools and many iterations to get reader feedback, pivot until you have the right
book and build traction once you do.

© 2021 - 2022 Bartłomiej Filipek


Contents

About the Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i


Why should you read this book? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i
Learning objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i
The structure of the book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii
Who is this book for? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
Reader feedback & errata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
Example code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv
Code license . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv
Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv
Special sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vi

About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii

Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viii

Revision History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix

1. Local Variables and Simple Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 1


Starting with simple types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Setting values to zero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Initialization with aggregates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Default data member initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2. Initialization With Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11


A simple class type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Basics of constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Body of a constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Adding constructors to DataPacket . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
CONTENTS

Compiler-generated default constructors . . . . . . . . . . . . . . . . . . . . . . . . 26


Explicit constructors and conversions . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Difference between direct and copy initialization . . . . . . . . . . . . . . . . . . . 32
Implicit conversion and converting constructors . . . . . . . . . . . . . . . . . . . . 34
Constructor summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

3. Copy and Move Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38


Copy constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Move constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Distinguishing from assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Adding debug logging to constructors . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Trivial classes and user-provided default constructors . . . . . . . . . . . . . . . . . 59

4. Delegating and Inheriting Constructors . . . . . . . . . . . . . . . . . . . . . . . 64


Delegating constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Inheriting constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

5. Destructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Objects allocated on the heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Destructors and data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Virtual destructors and polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Partially created objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
A compiler-generated destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Summary and use cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

6. Type Deduction and Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . 89


Deduction with auto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Rules for auto type deduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Deduction with decltype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Printing type info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Structured bindings in C++17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Lifetime extension, references, and loops . . . . . . . . . . . . . . . . . . . . . . . . 103
Almost Always Auto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

7. Quiz from Chapters 1…6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109


CONTENTS

8. Non-Static Data Member Initialization . . . . . . . . . . . . . . . . . . . . . . . . 112


How it works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Investigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Experiments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Other forms of NSDMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Copy constructor and NSDMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Move constructor and NSDMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
C++14 changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
C++20 changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
Limitations of NSDMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
NSDMI: Advantages and Disadvantages . . . . . . . . . . . . . . . . . . . . . . . . . 129
NSDMI summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

9. Containers as Data Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132


The basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Using std::initializer list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Example implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
The cost of copying elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Some inconvenience - non-copyable types . . . . . . . . . . . . . . . . . . . . . . . 146
More options (advanced) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

10. Non-regular Data Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150


Constant non-static data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Pointers as data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Smart pointers as data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
References as data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

11. Non-local objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170


Storage duration and linkage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Initialization of non-local static objects . . . . . . . . . . . . . . . . . . . . . . . . . 180
constinit in C++20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Static variables in a function scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
About static data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Motivation for inline variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Global inline variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
constexpr and inline variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
CONTENTS

12. Aggregates and Designated Initializers in C++20 . . . . . . . . . . . . . . . . . . 199


Aggregates in C++20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
The basics of Designated Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
Advantages of designated initialization . . . . . . . . . . . . . . . . . . . . . . . . . 204
Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

13. Techniques and Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208


Using explicit for strong types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Best way to initialize string data members . . . . . . . . . . . . . . . . . . . . . . 212
Reducing extra copies through emplace and in_place . . . . . . . . . . . . . . . . 215
The copy and swap idiom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
CRTP class counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Several initialization types in one class . . . . . . . . . . . . . . . . . . . . . . . . . 226
Meyer’s Singleton and C++11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
Factory with self-registering types and static initialization . . . . . . . . . . . . . . 231
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237

14. The Final Quiz And Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238


Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242

Appendix A - Rules for Special Member Function Generation . . . . . . . . . . . . 248


The diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

Appendix B - Quiz and Exercises Answers . . . . . . . . . . . . . . . . . . . . . . . . 254


The quiz from chapters 1…6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
The final quiz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Solution to the first coding problem, NSDMI . . . . . . . . . . . . . . . . . . . . . . 255
Solution to the second coding problem, NSDMI . . . . . . . . . . . . . . . . . . . . 255
Solution to the third coding problem, inline . . . . . . . . . . . . . . . . . . . . . 257
Solution to the fourth coding problem, fix code . . . . . . . . . . . . . . . . . . . . 257

References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
About the Book
Initialization in C++ is a hot topic! The internet is full of discussions about best practices,
and there are even funny memes on that subject. The situation is not surprising, as there are
more than a dozen ways to initialize a simple integer value, complex rules for the auto-type
deduction, data members, and object lifetime nuances.
And here comes the book.
Throughout this text, you will learn practical options to initialize various categories of
variables and data members in Modern C++. More specifically, this text teaches multiple
types of initialization, constructors, non-static data member initialization, inline variables,
designated initializers, and more. Additionally, you’ll see the changes and new techniques
from C++11 to C++20 and lots of examples to round out your understanding.
The plan is to explain most (if not all) parts of initialization, learn lots of excellent C++
techniques, and see what happens under the hood.

Why should you read this book?


With Modern C++ (since C++11), we have many new features to streamline work and
simplify our code. One area of improvement is the initialization. Modern C++ added new
initialization rules, trying to make it easy while keeping old behavior and compatibility
(mainly from the C language). Sometimes the rules might seem confusing and complex,
though, and even the ISO committee might need to correct some things along the way. The
book will help you navigate through those principles and understand this topic better. What’s
more, initialization is just one aspect of this text. You’ll learn all related topics around classes,
constructors, destructors, object lifetime, or even how the compiler processes data at start-up.

Learning objectives
The goal is to equip you with the following knowledge:
• Explain rules about object initialization, including regular variables, data members,
and non-local objects.

i
About the Book ii

• How to implement special member functions (constructors, destructors, copy/move


operations) and when they are helpful.
• How to efficiently initialize non-static data members using C++11 features like non-
static data member initialization, inheriting, and delegating constructors.
• How to streamline working with static variables and static data members with inline
variables from C++17.
• How to work with container-like members, non-copyable data members (like const
data members) or move-able only data members, or even lambdas.
• What is an aggregate, and how to create such objects with designated initializers from
C++20.

The structure of the book


The book contains 14 chapters in the following structure:
• Chapters 1 to 5 create a foundation for the rest of the book. They cover basic
initialization rules, constructors, destructors, and the basics of data members.
• Chapter 6 is a short quiz on constructors. You can check your knowledge from the first
“part” of the book.
• Chapter 7 (in progress): Type deduction.
• Chapter 8 describes Non-static Data Member Initialization (NSDMI), a powerful
feature from C++11 that improves how we work with data members. At the end of
the chapter, you can solve a few exercises.
• Chapter 9 discusses how to initialize container-like data members.
• Chapter 10 contains information about non-regular data members and how to handle
them in a class. You’ll learn about const data members, unique_ptr as a data member,
and references.
• Chapter 11 describes static non-local variables, static objects, various storage duration
options, and inline variables from C++17 and constinit from C++20.
• Chapter 12 moves to C++20 and describes Designated Initializers, a handy feature
based on similar thing from the C language.
• Chapter 13 shows various techniques like passing strings into constructors, strong
typing, CRTP class counter, Copy and swap idiom, and more.
• Chapter 14 is the final quiz with questions from the whole book.
About the Book iii

And there are two appendices:

• Appendix A - a handy guide about rules for compiler-generated special member


functions.
• Appendix B - answers to quizzes and exercises.

Who is this book for?


The book is intended for beginner/intermediate C++ programmers who want to learn various
aspects of initialization in Modern C++ (from C++11 to C++20).
You should know at least some of the basics of creating and using custom classes.
This text is also helpful for experienced programmers who know older C++ standards and
want to move into C++17/C++20.

Prerequisites
• You should have basic knowledge of C++ expressions and primitive types.
• You should be able to implement an elementary class with several data members. Know
how to create and manipulate objects of such a class in a basic way.

Reader feedback & errata


If you spot an error, a typo, a grammar mistake, or anything else (especially logical issues!)
that should be corrected, please send your feedback to [email protected].
Here’s the errata with the list of fixes:
https://www.cppstories.com/p/cppinitbook/
Your feedback matters! Writing an honest review can help with the book promotion and the
quality of my further work.
What’s more, the book has a dedicated page at GoodReads. Please share your feedback at:
C++ Initialization Story by Bartłomiej Filipek¹.
¹https://www.goodreads.com/book/show/62606823-c-initialization-story
About the Book iv

Example code
You can find source code of all examples in this separate GitHub public repository.
the link will appear later
You can browse individual files or download the whole branch:
the link will appear later

Code license
The code for the book is available under the Creative Commons License.

Formatting
Code samples are presented in a monospaced font, similar to the following example:
For longer examples:
Title Of the Example

#include <iostream>

int main() {
const std::string text { "Hello World" };
std::cout << text << '\n';
}

Or shorter snippets (without a title and sometimes include statements):

int foo() {
return std::clamp(100, 1000, 1001);
}

When available, you’ll also see a link to online compilers where you can play with the code.
For example:
About the Book v

Example title. Run @Compiler Explorer

#include <iostream>

int main() {
std::cout << "Hello World!";
}

You can click on the link in the title, and then it should open the website of a given online
compiler (in the above case, it’s Compiler Explorer). You can compile the sample, see the
output, and experiment with the code directly in your browser. Here’s a basic overview of
Compiler Explorer:

A Compiler Explorer layout used in the book

Snippets of longer programs were usually shortened to present only the core mechanics.

Syntax highlighting limitations

The current version of the book might show some limitations regarding syntax highlighting.
For example:

• if constexpr - Link to Pygments issue: C++ if constexpr not recognized (C++17) ·


Issue #1136².
• The first method of a class is not highlighted - First method of class not highlighted in
C++ · Issue #791³.
²https://github.com/pygments/pygments/issues/1136
³https://github.com/pygments/pygments/issues/791
About the Book vi

• Template method is not highlighted C++ lexer doesn’t recognize function if return type
is templated · Issue #1138⁴.
• Modern C++ attributes are sometimes not appropriately recognized.

Other issues for C++ and Pygments: C++ Issues · github/pygments/pygments⁵.

Special sections
Throughout the book, you can also see the following sections:

This is an Information Box with extra notes related to the current section.

This is a Warning Box with potential risks and threats related to a given topic.

This is a Quote Box. In the book, it’s often used to quote the C++ Standard.

⁴https://github.com/pygments/pygments/issues/1138
⁵https://github.com/pygments/pygments/issues?q=is%3Aissue+is%3Aopen+C%2B%2B
About the Author
Bartłomiej (Bartek) Filipek is a C++ software developer from a beautiful city Cracow in
Southern Poland. He started his professional career in 2007 and in 2010 he graduated from
Jagiellonian University with a Masters Degree in Computer Science.
Bartek currently works at Xara⁶, where he develops features for advanced document editors.
He also has experience with desktop graphics applications, game development, large-scale
systems for aviation, writing graphics drivers and even biofeedback. In the past, Bartek
has also taught programming (mostly game and graphics programming courses) at local
universities in Cracow.
Since 2011 Bartek has been regularly blogging at cppstories.com⁷ (started as bfilipek.com⁸).
The blog focuses on core C++ and getting up-to-date with the C++ Standards. He’s also a
co-organiser of the C++ User Group in Cracow⁹. You can hear Bartek in one @CppCast
episode¹⁰ where he talks about C++17, blogging and text processing.
Since October 2018, Bartek has been a C++ Expert for the Polish National Body which works
directly with ISO/IEC JTC 1/SC 22 (C++ Standardisation Committee). Bartek was awarded
his first MVP title for the years 2019/2020 by Microsoft.
In his spare time, he loves collecting and assembling Lego models with his son.
Bartek is the author of C++17 In Detail¹¹ and C++ Lambda Story¹²
⁶http://www.xara.com/
⁷https://www.cppstories.com]
⁸https://www.bfilipek.com
⁹https://www.meetup.com/C-User-Group-Cracow/
¹⁰http://cppcast.com/2018/04/bartlomiej-filipek/
¹¹https://leanpub.com/cpp17indetail
¹²https://leanpub.com/cpplambda

vii
Acknowledgements
This book wouldn’t be possible without valuable input from many C++ experts and friends.
I especially would like to thank to the following people:

• JFT (John Taylor),


• Mariusz Jaskółka,
• Florin Chertes (see his profile at LinkedIn¹³),
• Konrad Jaśkowiec (see his profile at LinkedIn¹⁴),
• Professor Boguslaw Cyganek (see his profile at AGH university page¹⁵),
• Dawid Pilarski (see his blog at panicsoftware.com¹⁶)
• Javier Estrada (see his blog at javierestrada.blog¹⁷),
• Jonathan Boccara (from fluentcpp.com/¹⁸),
• Andreas Fertig (see his blog at andreasfertig¹⁹),
• Peter Sommerlad (see his website and training info at sommerlad.ch/²⁰),
• Timur Doumler (see his website at timur.audio/²¹ and his Twitter²²).

They spent a lot of time on finding even little things that could be improved and extended.
Last but not least, I got a lot of feedback and comments from the blog readers, Patreon
Discord Server (See @C++Stories @Patreon²³), and discussions at C++ Polska²⁴. Thank you
all!
With all of the help from those kind people, the book quality got better and better!
¹³https://www.linkedin.com/in/florin-ioan-chertes-41b6845/
¹⁴https://pl.linkedin.com/in/konrad-ja%C5%9Bkowiec-84585159
¹⁵https://home.agh.edu.pl/~cyganek/
¹⁶https://blog.panicsoftware.com/
¹⁷https://javierestrada.blog/
¹⁸https://www.fluentcpp.com/
¹⁹https://andreasfertig.blog/
²⁰https://sommerlad.ch/
²¹https://timur.audio/
²²https://twitter.com/timur_audio
²³https://www.patreon.com/cppstories
²⁴https://cpp-polska.pl/

viii
Revision History
• 20th June 2022 - The first public version! The books is almost done. Missing parts:
some sections in 10. Containers as Data Members, some sections in 11. Non-regular
Data Members.
• 22nd June 2022 - new sections on NSDMI, direct init and parens, more about inheriting
constructors, link to GoodReads, wording, hotfixes.
• 24th June 2022 - updated the “copy and move constructor” chapter, typos and small
wording improvements.
• 16th July 2022 - Containers as Data Members chapter rewritten, noexcept consistency
and noexcept move operations advantages in the move constructor section, wording,
fixes, layout.
• 13th September 2022 - changed title to “C++ Initialization Story”, adapted book
structure, rewritten “Non-local objects” chapter (previously only on inline variables),
new extracted chapter on Techniques, new section on CRTP.
• 18th November 2022 - heavily updated and completed “Non-regular data members”
chapter, constinit and thread_local sections in the “Non-local objects” chapter,
filled the “implicit conversion” section in the Constructors chapter.
• 23rd December 2022 - content completed! Added Deduction chapter, filled missing
sections in the Techniques chapter. Layout improvements, a few more questions,
exercises and fixes.

ix
1. Local Variables and Simple Types
Let’s start simple and ask, “what is initialization?” When we go to the definition from
C++Reference¹, we can read:

Initialization of a variable provides its initial value at the time of construction.

We can translate this definition to the following example:

void foo() {
int x = 42;
// ... use 'x' later...
}

Above, we have a function with a local variable x. The variable is declared as integer and
initialized with the value 42. This is one of many ways you can assign that initial value. Here
are some more options:

struct Point { int x; int y; }; // declare a custom type


Point createPoint(int x) { return {x, -x}; }
int main() {
int x { 42 }; // list initialization
double y = { 100.0 }; // copy list initialization
auto ptr = std::make_unique<float>(90.5f); // auto type deduction
auto z = createPoint(42); // through a factory function
std::string s (10, 'x'); // calling a constructor
Point p { 10 }; // aggregate initialization
std::array<float, 100> numbers { 1.1f, 2.2f }; // array initialization
// ...
}
¹https://en.cppreference.com/w/cpp/language/initialization

1
Local Variables and Simple Types 2

You can also come up with many other forms of setting a value. We can also extend the
syntax on class data members, static variables, thread locals, or even dynamic memory
allocations.
In theory, initialization is simple: “put a value into a memory location of a newly created
variable”. However, such action relates to many parts of application code (local vs. non-local
scope vs. thread) and various places in the memory (like stack vs. heap). That’s why the
syntax or the behavior might be slightly different.
In C++, we have at least the following forms of initialization:

• aggregate initialization
• constant initialization
• default initialization
• direct initialization
• copy initialization
• list initialization
• reference initialization
• value initialization
• zero initialization
• plus related topics like copy elision, static variables, conversion sequences, constructors,
assignment, dynamic memory, storage, and more.

While the list sounds complex, we’ll move through those topics step by step revealing core
concepts. Later we’ll address more advanced examples and see what happens inside the C++
machinery.
While we can explain most cases on integers and other numerical types, it’s best to work
on something more practical. The book starts with some elementary custom types, then
considers various issues we might have with their early implementations. Later the types
will expand, giving us more context and compelling use cases.

Starting with simple types


Defining a class or a struct (a custom type) in C++ allows you to model your problem domain
and solve problems more naturally. Rather than working with a bunch of variables and
functions, it’s best to group them and provide a consistent API (Application Programming
Local Variables and Simple Types 3

Interface). C++ provides a set of built-in types, including boolean, integral, character, and
floating-point. Additionally, you can use objects from the Standard Library, like various
collections, std::string, std::vector, std::map, std::set, and many others. You can
collect these essential components and build your types.
To create a background for our main topic, let’s start with a type representing Car
Information for a car listing app. A system reads the car/truck information from a database
and displays it in the application. For an easy start, the type holds four members: name (a
std::string), production year, number of seats, and engine power.

Below there’s the first version of the code for that CarInfo type:
Ex 1.1. Simple CarInfo structure. Run @Compiler Explorer

#include <iostream>
#include <string>

struct CarInfo {
std::string name;
unsigned year;
unsigned seats;
double power;
};

int main() {
CarInfo firstCar;
firstCar.name = "Renault Megane";
firstCar.year = 2003;
firstCar.seats = 5;
firstCar.power = 116;
Local Variables and Simple Types 4

std::cout << "name: " << firstCar.name << '\n';


std::cout << "year: " << firstCar.year << '\n';
std::cout << "seats: " << firstCar.seats << '\n';
std::cout << "power (hp): " << firstCar.power << '\n';
}

In the above example, we defined a simple structure that holds data for a CarInfo. The code
is super simple, contains some issues, and follows the style of C++03. In the following few
chapters, I’ll guide you through the code and help you understand the problems and how to
eliminate them. We’ll also modernize it to include the latest C++ (up to C++20) features.
First: name, year, seats, and power are called non-static data members. Each instance of
the CarInfo class has its own set of those members. In other words, we group variables to
create a representation for models in our problem domain. A user-defined type might also
have static data members, which are data shared between all instances of a given type. For
example, we could imagine a static member variable called numAllCars that would indicate
the total number of cars created in our program. We’ll talk about static data members later
in chapter 11 Static Variables.
Now, let’s investigate the code in detail. The definition and the declaration of the variable
firstCar in the main() function:

CarInfo firstCar;

It is called default initialization and, since our struct is simple, will leave all data members
of built-in types with indeterminate values. Similarly, you can get the same (potentially
buggy effect) for simple types when declared in function (as such variables have automatic
storage duration) ²:

void foo() {
int i; // indeterminate value!
double d; // indeterminate value!
}

The std::string data member name, on the other hand, will have an empty state (an empty
string) because its default constructor will be called. More on that later.
²In contrast, static and thread-local objects will be zero-initialized.
Local Variables and Simple Types 5

Once the object is created and uninitialized, we can access its members and set proper values.
By default, struct has public access to its members (and class has private access). This way,
we can access and change their values directly.

What is “Automatic Storage Duration”?


All objects in a program have four possible ways to be “stored”: automatic, static,
thread, or dynamic. Automatic means that the storage is allocated at the start of
the scope, like in a function. Most local variables have automatic storage duration
(except those declared as static, extern, or thread_local). We’ll discuss this
more in the chapter on non-local objects³.

Setting values to zero


You might feel very unsatisfied that after creating a CarInfo object, most data members
have some indeterminate values. We can fix this and make sure the data is at least set to
“zero”. Have a look:
Ex 1.2. Value initialization for the CarInfo structure. Run @Compiler Explorer
CarInfo emptyCar{};
std::cout << "name: " << emptyCar.name << '\n';
std::cout << "year: " << emptyCar.year << '\n';
std::cout << "seats: " << emptyCar.seats << '\n';
std::cout << "power (hp): " << emptyCar.power << '\n';

The output:

name:
year: 0
seats: 0
power (hp): 0

The initialization with empty braces {} is called value initialization and, by default (for built-
in types and classes with default constructors that are neither user-provided nor deleted),
sets data to “zero” (adapted for different types). This is similar to declaring and defining the
following variables:
³chapterinlinevars
Local Variables and Simple Types 6

int i{}; // i == 0
double d{}; // d == 0.0
std::string s{}; // s is an empty string

int j = {}; // other form of value initialization


std::string str = {}; // ...

This time the storage duration doesn’t matter, and value initialization works the same for
static, dynamic, thread-local, or automatic variables. For types with default constructors
(more on that later), the code will call them and, in the case of string s; will initialize it
to an empty string.

Initialization with aggregates


Our structure is very simple, and for such types, C++ has special rules where we can initialize
their internal values with so-called aggregate initialization. We can use such syntax also for
arrays. Here are some basic examples:
Ex 1.3. Aggregate Initialization basic syntax. Run @Compiler Explorer

// arrays:
int arr[] { 1, 2, 3, 4 };
float numbers[] = { 0.1f, 1.1f, 2.2f, 3.f, 4.f, 5. };
int nums[10] { 1 }; // 1, and then all 0s

// structures:
struct Point { int x; int y; };
struct Line { Point p1; Point p2; };
Line longLone {0, 0, 100, 100};
Line anotherLine = {100}; // rest set to 0
Line shortLine {{-10, -10}, {10, 10}}; // nested

In summary, for the above code:

• Each array element, or non-static class member, in order of array subscript/appear-


ance in the class definition, is copy-initialized from the corresponding clause of the
initializer list.
Local Variables and Simple Types 7

• You can use list initialization for arrays, and when the number of elements is not
provided, the compiler will deduce the count.
• If you pass fewer elements in the initializer list than the number of elements in the
array, the remaining elements will be value initialized. For built-in types, it means the
value of zero.
• For structures, you can use a single initializer list or nested one; the expansion will be
recursive.
• If you provide fewer values than the number of data members in the aggregate, then the
remaining data members (in the declaration order) will be effectively value initialized.
The first bullet point says that each element is copy initialized. We’ll return to this topic and
explain the difference between a copy vs. direct initialization syntax once we know explicit
constructors.
For our structure, we can write the following test code:
Ex 1.4. Aggregate initialization for the CarInfo structure. Run @Compiler Explorer
struct CarInfo {
std::string name;
unsigned year;
unsigned seats;
double power;
};

void printInfo(const CarInfo& c) {


std::cout << c.name << ", "
<< c.year << " year, "
<< c.seats << " seats, "
<< c.power << " hp\n";
}

int main() {
CarInfo firstCar{"Megane", 2003, 5, 116 };
printInfo(firstCar);
CarInfo partial{"unknown"};
printInfo(partial);
CarInfo largeCar{"large car", 1975, 10};
printInfo(largeCar);
}
Local Variables and Simple Types 8

This will output:

Megane, 2003 year, 5 seats, 116 hp


unknown, 0 year, 0 seats, 0 hp
large car, 1975 year, 10 seats, 0 hp

Without going into full definitions, an aggregate means a simple type (or an array) with all
public data members, no virtual functions, and user-provided constructors.
We’ll discuss aggregates in further parts of the book (and see the full definition of that
category of types). And there’s a dedicated chapter about Aggregates and Designated
Initialization in C++20.

Default data member initialization


What if you want to provide some default value for your data member? With value
initialization, you can get zeros for various types, but sometimes it might not be good enough.
Since C++14, we can leverage Non-static Data Member Initializers (NSDMI), also called
Default Member Initializers, to provide default values for aggregates. Have a look:
Ex 1.5. Default member initialization and aggregates. Run @Compiler Explorer

#include <iostream>
#include <string>

struct CarInfo {
std::string name { "unknown" };
unsigned year { 1920 };
unsigned seats { 4 };
double power { 100. };
};

void printInfo(const CarInfo& c) { /* */ }

int main() {
CarInfo unknown;
printInfo(unknown);
CarInfo zeroed{};
Local Variables and Simple Types 9

printInfo(zeroed);
CarInfo partial{"large car", 1975};
printInfo(partial);
}

This will print:

unknown, 1920 year, 4 seats, 100 hp


unknown, 1920 year, 4 seats, 100 hp
large car, 1975 year, 4 seats, 100 hp

The syntax is quite intuitive; you can initialize a data member at the place where it’s declared.
This can prevent accidental bugs where your data has some indeterminate value. As you
can see from the example, even if you use default initialization or value initialization, data
members will get values that were provided in the struct declaration. If you give fewer
values in the aggregate initializer, the remaining members will get their defaults from the
declaration.
Technically, in-class member initializers have been available since C++11, but aggregate
types weren’t supported initially. In this section, we’ve only scratched the surface of
this handy technique. See the dedicated chapter for this topic: Non-static data member
initialization chapter.

Summary
In this chapter, we covered some simple custom types and looked at ways to initialize their
data members. We went from objects with indeterminate values to zero initialization, and
then we learned about aggregates and techniques to provide default values.
Things to keep in mind:

• Default initialization for objects and variables yields indeterminate values for built-
in types or default-initialize complex types (like std::string and set it to an empty
string). That’s why it’s essential to be sure your objects and simple variables are
always initialized.
• Value initialization like int x{}; for built-in types effectively yields zero initialization
for them so that they will be zero (in their type).
Local Variables and Simple Types 10

• With value initialization CarInfo car{}; all data members will be zero-initialized
(for built-in types) or default initialized for complex types.
• Aggregates are simple types or arrays with all public data members; we can initialize
them with an aggregate initialization syntax.
• Thanks to the in-class member initializer feature, you can provide default values for
your data members.

What’s next?
While simple types are handy, in C++, we often need to build large objects where data
members depend on each other or have invariants. In such cases, it’s best to hide them
behind member functions and give access to them under certain conditions. In the next
chapter, we’ll look at class’s and constructors. We’ll also expand the knowledge that we
got so far.
2. Initialization With Constructors
In the previous chapter, you’ve seen that C++ might treat simple structures with all public
data members as an aggregate class. Still, aggregates are insufficient if we want better data
encapsulation and a more complex class API. For full flexibility in C++, we can leverage
constructors that are special member functions invoked when an object is created.

A simple class type


As a background example, let’s create a type that will hold some elementary network data. To
complicate things, we’d like to compute a basic checksum for the data part. Such a checksum
might be handy for checking if the data was transferred correctly across the Internet (read
more @Wikipedia¹).
Ex 2.1. Simple DataPacket class. Run @Compiler Explorer

size_t calcCheckSum(const std::string& s) {


return std::accumulate(s.begin(), s.end(), 0uz);
}
class DataPacket {
std::string data_;
size_t checkSum_;
size_t serverId_;
public:
const std::string& getData() const { return data_; }
void setData(const std::string& data) {
data_ = data;
checkSum_ = calcCheckSum(data);
}
size_t getCheckSum() const { return checkSum_; }
size_t getServerId() const { return serverId_; }
void setServerId(size_t serverId) { serverId_ = serverId; }
};

¹https://en.wikipedia.org/wiki/Checksum

11
Initialization With Constructors 12

The class above contains three non-static data members: data_, checkSum_, and serverID_.
I’m using the underscore suffix to indicate private data members, a common practice in
many codebases. See Google C++ Style Guide².
To keep things simple, I implemented the calcCheckSum function in terms of
std::accumulate(), which is an algorithm from the C++ Standard Library. This
code starts from 0 and adds numerical values of letters from the input std::string. Since
C++23, we can use the 0UZ integer literal to represent the size_t so that it matches with
the return type for the function; alternatively, we could use static_cast<size_t> or
UL/ULL for 32/64-bit systems respectively. For example, for "HELLO", we’ll get the following
computations:

Calculating simple checksum for a string

DataPacket has so-called getters and setters - functions that return or change a particular
data member. For example getData() returns the data_ data member, while setData(...)
allows us to change it.
One important topic is that getters usually have const applied at the end. This means that
a given member function is constant and cannot change the value of the members (unless
they are mutable). If you have a const object, you can only call its const member functions.
Applying const might improve program design as it’s usually easier to reason about the state
of const instances. For more information, see this C++ core guideline: Con.2: By default,
make member functions const³.

Member functions might also have noexcept specifier applied. However, this
topic is outside the scope of the book and won’t be covered. You can find more
@C++Reference - noexcept specifier⁴.
²https://google.github.io/styleguide/cppguide.html#Variable_Names
³https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#con2-by-default-make-member-functions-const
⁴https://en.cppreference.com/w/cpp/language/noexcept_spec
Initialization With Constructors 13

Here’s the continuation of the example where we create and use the object of the DataPacket
class:
Ex 2.2. Simple DataPacket class, continuation. Run @Compiler Explorer
int main() {
DataPacket packet;
packet.setData("Programming World");
std::cout << packet.getCheckSum() << '\n';
}

The code doesn’t access data members directly but calls member functions to operate on the
object and change its properties.
You can notice the public and private parts in the class declaration. The order of those
sections is just a coding convention, and they group elements together based on their access
modifier. In short, a member under the public keyword can be accessed from the outside
(like calling a member function or accessing a data member). On the other hand, members
under the private section cannot be accessed from outside⁵. In C++, you can also add
protected to your class declaration, which means that member functions or fields are
not accessible outside, but they are accessible to all inherited classes (assuming public
inheritance, see more on that in the inheritance section further in the book).
For example, in the main() function above, I cannot write:

DataPacket packet;
packet.serverId = 10; // error: 'size_t DataPacket::serverId' is private...

The only difference between class and struct in C++ is that class has private
as the default access modifier and private inheritance, while struct has both
specified as public. Some C++ guidelines, for example, Google Style Guide see
this link⁶, suggest using struct only for smaller, “passive” types, with only public
data members. The C++ Core Guidelines also recommend using class if any
member is not public; see C++ Core Guidelines - C.8⁷.

Since our class doesn’t have any user-defined constructors (more on them in the next section),
we can also use value initialization syntax to set values to zero or default values:
⁵Unless accessed by friend functions or classes.
⁶https://google.github.io/styleguide/cppguide.html#Structs_vs._Classes
⁷https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c8-use-class-rather-than-struct-if-any-member-is-non-
public
Initialization With Constructors 14

Ex 2.3. Value initialization for the DataPacket class. Run @Compiler Explorer
int main() {
DataPacket packet{};
std::cout << "data: " << packet.getData() << '\n';
std::cout << "checkSum: " << packet.getCheckSum() << '\n';
std::cout << "serverId: " << packet.getServerId() << '\n';
}

This will generate the following output:

data:
checkSum: 0
serverId: 0

However, the main difference now is that because we moved the data members to the private
section, the class is not an aggregate. That’s why we cannot use aggregate initialization to
set all values at once. To fix this, we need to look at constructors. And that is the plan for
further sections.

Basics of constructors
A constructor is a special member function that does not have a name, but we declare/define
it using the enclosing class name⁸. You cannot invoke a constructor like other member
functions. Instead, the compiler calls it when an object of its class is being initialized. It
has the following basic syntax:

A constructor has the following parts:


⁸See the full definition at https://timsong-cpp.github.io/cppwp/n4868/class.ctor.general
Initialization With Constructors 15

• constructor has no name, but we define it using the name of the class,
• optional explicit - keyword to block implicit conversions on a given class type,
• ClassName - the name of the given class type (they have to match),
• parameter-list- a list of parameters, as in a regular function, might be empty
• optional = default/=delete specifies if a constructor should be deleted (not present)
or defaulted by the compiler,
• : - indicates the start of the member/base initialization list, required when
base-class-initializer or member-init lists are present,
• optional base-class-initializer - a list of base classes’ constructors that we
explicitly want to call,
• optional member-init - a list of data members where we can directly initialize them,
• {/*body*/} - a function body.

You can also apply noexcept, [[attributes]], constexpr, and consteval on


a constructor, but the full explanation of those additional properties goes beyond
the scope of the book. Read more at C++Reference - Constructors and member
initializer lists⁹.

For illustrative purposes, you can find a simple class type with two data members below.
The Product class will serve as a toy example, and then we’ll apply the knowledge to the
DataPacket class I plan to update. Let’s have a look at one snippet:

class Product {
public:
Product() : id_{-1}, name_{"none"} { } // a default constructor
explicit Product(int id, const std::string& name)
: id_{id}, name_{name} { }
private:
int id_;
std::string name_;
};

The above example shows a class with two constructors. The first is called a default
constructor; it has no arguments. The second one takes two arguments. As you can notice,
⁹https://en.cppreference.com/w/cpp/language/constructor
Initialization With Constructors 16

C++ allows multiple constructors that look like overloaded functions (they differ by the
number or types of arguments). Each constructor also has a regular function body where you
can execute some code; in our case, they are both empty for now. I also applied the explicit
keyword on the second constructor; we’ll talk about it later in the explicit constructors
section.
The primary function of constructors is to perform some actions at the start of a lifetime of
an object. Usually, it means data member initialization, resource allocation (opening a file, a
socket, memory allocation), or even doing some special logic (like logging).
In our case, constructors touch only data members inside a special section of constructors
called member initializer list: like, id_{-1}, name_{"none"}. Inside this initializer list, we
can also call constructors of base classes (if any). Later, we’ll address inheritance in the
Inheritance section.
The member initializer list is more efficient than using the body of a constructor. Sometimes
it’s even the only option to initialize the value, as with types that are not assignable. See the
following and wrong alternative:

class Product {
public:
Product() { id_ = 0; name_ = "none"; } // bad code, only for illustration
private:
int id_;
std::string name_;
};

The code will yield the same values for data members as in the previous example, but the data
members are set in two steps rather than one. With the member initializer list, data members
are set directly, same as calling: int id_ { 0 } or std::string name_ {"none"}. On the
other hand, if we use assignment in the constructor body, it requires two steps:

// step 1: default init:


int id_; // indeterminate value!
std::string name_; // default ctor called
// step 2: assignment:
id_ = 0;
name_ = "none";
Initialization With Constructors 17

While this might not be a big issue for built-in simple types like int , you’ll need some
more CPU cycles for larger objects like strings. Please don’t write such code and aim for a
member initializer list to initialize your data members efficiently.
There’s also one important aspect about the initializer list: the order of initialization. This is
covered in The C++ Specification: 11.10.3 Classes¹⁰:

Non-static data members are initialized in the order they were declared in the class
definition (regardless of the order of the mem-initializers).

When I write the constructor in the following way:

Product() : name_{"none"}, id_{-1} { }

The values will be set correctly, but the order will differ from what we think. Here’s the
warning from GCC compiled with -Wall option (experiment @Compiler Explorer¹¹):

In constructor 'Product::Product()':
warning: 'Product::name_' will be initialized after [-Wreorder] ...
warning: 'int Product::id_' [-Wreorder] ...

The initialization order might be critical when you imply some dependency on the values.
For example, we can write the following artificial sample:

struct S {
int x;
int y;
int z;
S(): x{0}, y{1}, z{x+y} { }
// S(): y{0}, z{0}, x{z+y}, { }
};

In the above example, the first constructor initializes x and y and then uses those values to
initialize z. This is complicated and might be hard to read, but it works correctly. On the
¹⁰https://timsong-cpp.github.io/cppwp/n4868/class.base.init#13.3
¹¹https://godbolt.org/z/jE77169qd
Initialization With Constructors 18

other hand, in the second (commented out) constructor, the order of initialization will create
an undefined behavior for initializing x, as z and y won’t be initialized yet. It’s best to avoid
such dependencies to minimize the risk of bugs.
Let’s see how a constructor works by creating some objects of the Product class:

Product none;

In the first example, we created the none object, which is default constructed. The compiler
will call our default constructor; thus, the data members will be initialized to id_ = -1 and
name_ = "none".

Product car(10, "car");

The example uses the form of direct initialization, which calls the constructor with two
arguments. After the call, data members will be: id_ = 10 and name_ = "car".
And the last example:

Product tvSet{100, "tv set" };

This time we also called a constructor with two arguments, but the syntax is called * direct
list initialization* - "{}". Please notice that I also used this form of initialization inside the
initializer list in constructors.
Here’s the complete example:
Ex 2.4. Constructors for the Product class. Run @Compiler Explorer

#include <iostream>
#include <string>

class Product {
public:
Product() : id_{-1}, name_{"none"} { } // a default constructor
explicit Product(int id, const std::string& name)
: id_{id}, name_{name} { }

int Id() const { return id_; }


std::string Name() const { return name_; }
Initialization With Constructors 19

private:
int id_;
std::string name_;
};

int main() {
Product none;
std::cout << none.Id() << ", " << none.Name() << '\n';

Product car(10, "super car");


std::cout << car.Id() << ", " << car.Name() << '\n';

Product tvSet{77, "tv set" };


std::cout << tvSet.Id() << ", " << tvSet.Name() << '\n';
}

You might also scratch your head and ask why I declared the name parameter as const
std::string& rather than just std::string&. First, we don’t want to modify this parameter
in the constructor’s body. What’s more, const T& - const references can bind to “temporary”
objects like a string literal "super car". Without a const reference, we would have to pass
some named string object. Alternatively, we can pass the name by value and perform a
“move operation” on that argument. Further in the book, I’ll address this topic in detail; see
chapter: A Use Case - Best Way to Initialize string Data Members.

More on uniform initialization

The syntax with curly braces “{}” is, in fact, a powerful feature of C++11 called list
initialization, also called “uniform” or “brace” initialization. The primary motivation was
to create a uniform way to initialize data and avoid some issues.
For example, because of the C++ language grammar rules, the following line won’t compile:
Initialization With Constructors 20

Ex 2.5. The Most Vexing Parse Rule. Run @Compiler Explorer

#include <iostream>
#include <string>

struct Box { };

struct Product {
Product(): name{"default product"} { }
Product(const Box& b) : name{"box"}{ }
std::string name;
};

int main() {
Product p(); // << 1.
std::cout << p.name;
Product p2(Box()); // << 2.
std::cout << p2.name;
}

The line Product p(); looks innocent, and one could expect a default constructor to be
called. Unfortunately, the compiler recognizes it as a declaration of a function! There’s a C++
rule which says that anything that can be parsed as a declaration must be interpreted as one.
In our context, the line might mean a local function of a name p returning Product and
taking no arguments. Similarly, the line with p2 also causes compiler errors, and this time
the compiler thinks we declare a local function p2 returning a Product and taking Box as
an argument.
But fortunately, we have at least two ways of fixing it:

Product p{};
Product p1;
Product p2{Box()};
Product p3{Box{}};

It works as expected, and the list initialization syntax is the most consistent option. Try to
modify the example @Compiler Explorer¹² and fix the code. Here’s a good article if you want
¹²https://godbolt.org/z/c48K7c9vq
Initialization With Constructors 21

to know more about this rule: The Most Vexing Parse: How to Spot It and Fix It Quickly -
Fluent C++¹³.
List initialization also handles multiple arguments and can be used inside initializer lists:
Ex 2.6. Multiple arguments and braces. Run @Compiler Explorer

#include <iostream>
#include <string>

struct Product {
Product() : name{"default product"}, value{} { }
Product(char a, char b, char c, double v)
: name{a, b, c}, value{v} { }

std::string name;
double value;
};

int main() {
Product def{};
std::cout << def.name << ", " << def.value << '\n';
Product p{'x', 'y', 'z', 100.0};
std::cout << p.name << ", " << p.value;
}

In the above example, we not only used list initialization to call the Product constructor
with four arguments, but we also used it to initialize the name and value data members.
What’s more, the curly list initialization has the following advantages:

• the syntax is similar to aggregate initialization,


• adds a way to initialize containers with a list of the objects. For example,
std::vector<int> v { 1, 2, 3, 4 },
• allowing for a safer way of initialization that checks for narrowing. For example, int
v{10.3} won’t compile and reports a narrowing error, while int v(10.3) works and
might produce an unwanted result.

There are some annoyances with list initialization through. For example:
¹³https://www.fluentcpp.com/2018/01/30/most-vexing-parse/
Initialization With Constructors 22

std::vector<int> vec1 { 1, 2 }; // holds two values, 1 and 2


std::vector<int> vec2 ( 1, 2 ); // holds one value, 2!

Above you can see a very similar declaration of vectors, but when used with list initialization,
you end up with a different vector than when using direct initialization. The list version
calls a special constructor taking std::initializer_list<int>, while the second calls a
constructor taking (size_type count, const int& value = int()).
Additionally, for auto type deduction in C++14:

auto i = 42; // i is an int with value 42


auto j(42); // j is an int with value 42
auto k{42}; // k is a std::initializer_list<int> until C++17!

Fortunately, this “inconsistency” was fixed in C++17, and now auto k{42} deduces an int.
See more C++17 in details: fixes and deprecation @C++ Stories¹⁴.
C++ Core Guidelines suggest sticking to this way of initialization, as its benefits outweigh
the opposing sides. See ES.23¹⁵

ES.23: Prefer the {}-initializer syntax


Reason: Prefer {}. The rules for {} initialization are simpler, more general, less ambiguous,
and safer than for other initialization forms. Use = only when you are sure there can be
no narrowing conversions. For built-in arithmetic types, use = only with auto. Avoid ()
initialization, which allows parsing ambiguities.

The guideline also mentions some exceptions:

Exception: For containers, there is a tradition for using {…} for a list of elements and (…)
for sizes: vector<int> v(10); // 10 elements with the default value 0
vector<int> v2{10}; // vector of 1 element with the value 10

In this book, I’ll use {} for variable initialization and mention exceptions if needed.
¹⁴https://www.cppstories.com/2017/05/cpp17-details-fixes-deprecation/#new-auto-rules-for-direct-list-initialization
¹⁵https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es23-prefer-the--initializer-syntax
Initialization With Constructors 23

Body of a constructor
After the member initializer list, each constructor has a regular function body, { ... },
where you can perform additional steps to modify variables or call other functions. The only
difference between a regular function and a constructor is that a constructor cannot return
any values. Typically, a constructor throws an exception to report an error.
Here’s a small example that shows how to add some logging into a constructor body and
throw an exception on error:
Ex 2.7. Logging in a constructor. Run @Compiler Explorer

#include <iostream>
#include <stdexcept> // for std::invalid_argument

constexpr int LOWEST_ID_VALUE = -100;

class Product {
public:
explicit Product(int id, const std::string& name)
: id_{id}, name_{name} {
std::cout << "Product(): " << id_ << ", " << name_ << '\n';
if (id_ < LOWEST_ID_VALUE)
throw std::invalid_argument{"id lower than LOWEST_ID_VALUE!"};
}
std::string Name() const { return name_; }
private:
int id_;
std::string name_;
};

int main() {
try {
Product car(10, "car");
std::cout << car.Name() << " created\n";
Product box(-101, "box");
std::cout << box.Name() << " created\n";
}
catch (const std::exception& ex) {
std::cout << "Error - " << ex.what() << '\n';
Initialization With Constructors 24

}
}

The above example shows a constructor that performs logging and basic parameter checking.
It uses a LOWEST_ID_VALUE, a global constant marked with the constexpr keyword (the
second time we used this keyword).

The constexpr specifier has been available since C++11 and guarantees that a
value is available at compile time for constant expressions. For example, you
can use such a variable to set the number of elements in a C-style array. It’s
often perceived as a “type-safe macro definition”. The keyword applies to all
built-in trivial types like integral values, floating-point, or even character literals
(in C++20, std::string might be used in the constexpr context but not for
variables available at runtime); there’s also a way to declare custom constexpr-
ready types. You can also create a function to be constexpr and possibly evaluate
it at compile-time; however, we won’t cover such functions in this book. See more
at C++Reference - constexpr¹⁶.

If you run this program, you can see the following output:

Product(): 10, car


car created
Product(): -101, box
Error - id cannot be lower than LOWEST_ID_VALUE!

Please notice that while two constructors were called, we can see that only the first one
succeeded. Since the constructor for box threw an exception, this object is not treated as
fully created. More on that later when we’ll talk about destructors.

Adding constructors to DataPacket


After the introduction, we can start adding constructors to our DataPacket class.

¹⁶https://en.cppreference.com/w/cpp/language/constexpr
Initialization With Constructors 25

Ex 2.8. Adding constructors. Run @Compiler Explorer

class DataPacket {
std::string data_;
size_t checkSum_;
size_t serverId_;
public:
DataPacket() : data_{}, checkSum_{0}, serverId_{0} { }
explicit DataPacket(const std::string& data, size_t serverId)
: data_{data}, checkSum_{calcCheckSum(data)}, serverId_{serverId}
{ }

const std::string& getData() const { return data_; }


size_t getCheckSum() const { return checkSum_; }
size_t getServerId() const { return serverId_; }
};

And here’s the demo code that creates some objects:


Ex 2.9. Adding constructors, Demo. Run @Compiler Explorer

void printInfo(const DataPacket& packet) {


std::cout << "data: " << packet.getData() << '\n';
std::cout << "checkSum: " << packet.getCheckSum() << '\n';
std::cout << "serverId: " << packet.getServerId() << '\n';
}

int main() {
DataPacket empty;
printInfo(empty);
DataPacket zeroed{};
printInfo(zeroed);
DataPacket packet{"Hello World", 101};
printInfo(packet);
DataPacket reply{"Hi, how are you?", 404};
printInfo(reply);
}

The output:
Initialization With Constructors 26

data:
checkSum: 0
serverId: 0
data:
checkSum: 0
serverId: 0
data: Hello World
checkSum: 1052
serverId: 101
data: Hi, how are you?
checkSum: 1375
serverId: 404

In the above example, we used two constructors:

• The first is a default constructor and initializes data members to default values. It will
be called for default and value initialization.
• The second constructor takes several arguments and matches them with data members.
This constructor makes it easy to pass parameters all at once (previously, we needed
to call setters). This one takes two parameters, but we can initialize as many data
members as we need. For example, the constructors ensure the checkSum_ variable
matches data_. Since those two members are related, thanks to constructors and the
setData member function, we keep the relation safe.

We can also use default member initializers inside a class, but we’ll address that in detail in
a separate chapter.

Compiler-generated default constructors


While C++ allows you to implement various constructors, it can make your life easier by
automatically declaring and defining an implicit default constructor.
In other words, if you write a class type with no default constructor:
Initialization With Constructors 27

class Example {
public:
std::string Name() const { return name_; }
private:
std::string name_;
};

Then the compiler will create an implicit empty constructor:

inline Example() noexcept { }

A simple rule is that if a class has no user-declared constructors, the compiler will create a
default one if possible.
Have a look:
Ex 2.10. Implicit default constructor. Run @Compiler Explorer
struct Value {
int x;
};

struct CtorValue {
CtorValue(int v): x{v} { }
int x;
};

int main() {
Value v; // fine, default constructor available
// CtorValue y; // error! no default ctor available
CtorValue z{10}; // using custom ctor
}

As you can see above, the compiler will create an implicit default constructor for the Value
class (since it has no other constructors), but it won’t generate a default constructor for the
CtorValue class. Also, notice that Value::x will have an indeterminate value as a default
constructor is empty and won’t set any value for x.

Default constructors only default-initialize data members, so in the case of built-in


types, it means indeterminate values!
Initialization With Constructors 28

You can control the creation of such a default constructor using two keywords, default
and delete. In short, default tells the compiler to use the default implementation, while
delete blocks the implementation.

Ex 2.11. Default and Delete Constructors. Run @Compiler Explorer

struct Value {
Value() = default;
int x;
};

struct CtorValue {
CtorValue() = default;
CtorValue(int v): x{v} { }
int x;
};

struct DeletedValue {
DeletedValue() = delete;
DeletedValue(int v): x{v} { }
int x;
};

int main() {
Value v; // fine, default constructor available
CtorValue y; // ok now, default ctor available
CtorValue z{10}; // using custom ctor
// DeletedValue w; // err, deleted ctor!
DeletedValue u{10}; // using custom ctor
}

In the above example, you can see that we declare Value() = default; this tells the
compiler to create an empty (doing nothing) implementation. Also, in the CtorValue class,
we also use the same technique, and, as you can notice, the default construction works now.
The third class has = delete as its default constructor, and you’ll get an error if you want
to create an object of this class using its default constructor.
The implicit default constructor won’t be created if your type has data members that are
not default-constructible or inherits from a type that is not default-constructible. That
Initialization With Constructors 29

includes references, const data members, unions, and others. See the complete list here
@C++Reference¹⁷.

You may also ask what’s the difference between Value() = default and
Value() { }; they are both “empty”. Still, according to the C++ Standard, the
second constructor is considered user-declared or user-provided and has some
consequences in the type characteristics. We’ll cover that later once we cover copy
constructors in the section: Trivial classes and user-declared/user-provided default
constructors.

Explicit constructors and conversions


Before we move on, it’s essential to tackle one important case: the explicit keyword, which
can be applied before a constructor declaration.
Why is it important? And what does this keyword mean?
In short, it prevents implicit conversions and might sometimes make code easier to read.
As an experiment, let’s start with the following code:

struct Product {
Product() : name{"default product"}, value{} { }
Product(int v) : name{"basic"}, value{v} { }
Product(const std::string& n, int v)
: name{n}, value{v} { }

std::string name;
int value;
};

The code looks fine, but now you can create Product objects in a bit unusual way:

Product numbers = 100.2; // copy initialization


Product box = {"a box", 1}; // copy list-initialization
¹⁷https://en.cppreference.com/w/cpp/language/default_constructor#Deleted_implicitly-declared_default_constructor
Initialization With Constructors 30

We can read that those two lines create products, but what values do the data members
get? It needs to be clarified! The case in the first line is especially interesting, as I passed a
double value of 100.2, and the compiler tried to convert it into the int type (a narrowing
conversion) and then passed it to the constructor.
What’s more, it’s even more problematic with implicit conversions for function calls:
Ex 2.12. Implicit Conversions. Run @Compiler Explorer

void printProduct(const Product& prod) {


std::cout << prod.name << ", " << prod.value << '\n';
}

int main() {
double someRandomNumber = 100.1;
printProduct(someRandomNumber);
printProduct({"a box", 2});
}

The output:

basic, 100
a box, 2

The key idea is to understand: when you pass arguments into a function call, then the
compiler performs copy initialization on the arguments.
As you can see, the main issue is with constructors that take only one argument (or have
other arguments set to some default value). But even with several arguments, the conversion
can happen when you pass an initialization list.
To prevent such unwanted and unexpected conversions, it’s good to apply the explicit
keyword.
When we apply it:

explicit Product(int v) : name{"basic"}, value{v} { }


explicit Product(const std::string& n, int v) : name{n}, value{v} { }

The compiler will report the following errors:


Another random document with
no related content on Scribd:
»Jumala tulee lihaksi aikakaudesta aikakauteen maailman
lunastukseksi… Ei ole ehdoton sääntö, että hän ilmestyisi
ihmisolennon hahmossa…. Yhtä hyvin hän sen voi tehdä
abstraktisen periaatteen tai maailmata lumoavan suuren aatteen
hahmossa… Uusi ilmestys on Swadeši-Evankeliumi.»

Evankelista myöntää, että voi hymyillä tälle todistukselle, jos


Swadešissa näkee vain ulkolaisten kankaiden hylkäämisen. Mutta
tämä kysymys on vain laajan, »koko maailmaa sen vihamielisistä
riidoista vapauttamaan ja ihmiskuntaa tasa-arvoiseksi tekemään
määrätyn uskonnollisen periaatteen» käytäntöönsovittamista. Sen
ydin sisältyy hindulaisiin Pyhiin kirjoituksiin. Kas tässä:

»Sinun oma Dharmasi, vaikka vailla ansioita, on paras, Sinulle


vieraan Dharman saavuttaminen on aina vaarojen saartama. Pyri
vain sellaiseen onneen, jonka ydin on velvollisuus.»

Tämä Swadešin perusajatus nojautuu uskoon »yhteen Jumalaan,


joka ikuisiksi ajoiksi on huolehtinut maailmankaikkeuden onnesta.
Tämä Jumala on antanut jokaiselle ihmisolennolle soveltuvan
ympäristön, hänelle määrätyn erikoistehtävän mukaan. Ihmisen
kaikkien toimenpiteitten tulee mukautua hänen omaan
elämäntilanteeseensa… Emme voi itse valita kulttuuria enempää
kuin syntymäämme, perhettämme, maatamme; meidän on vain
hyväksyttävä se, minkä Jumala on meille antanut, meidän on
hyväksyttävä perinnäistapamme Jumalalta tulleina, ja meidän ankara
velvollisuutemme on niihin mukautua. Niiden pelkääminen olisi
syntiä.»

Näistä uskonkappaleista seuraa että yhden maan kansalaisen ei


pidä huolehtia muiden maiden kansalaisista.
»Swadešin-palvoja ei ota koskaan osalleen turhaa tehtävää
koettaa parantaa maailmaa, koska hän uskoo että maailma on
liikkunut ja tulee liikkumaan määrättyjen Jumalan suunnitelmien
mukaan. Ei pidä odottaa jonkin maan kansan huolehtivan toisen
maan tarpeista ihmisystävällisistäkään syistä; ja vaikkakin tämä olisi
mahdollista, ei se ole toivottavaa… Oikea Swadešin -palvoja ei
unohda, että jokainen ihmisolento on hänen veljensä mutta hänen on
silti pysyttävä syntymässä hänelle määrätyssä tehtävässä… Meidän
on palveleva niin hyvin syntymävuosisataamme kuin
syntymämaatamme kaikin voimin. On etsittävä sielun vapauttamista
oman uskontomme ja oman sivistyksemme pohjalta.»

Onko kansan edes luvallista kehittää vaurastumisensa välikeinoja:


kauppaa ja teollisuutta. Ei suinkaan. Inhoittava into pyrkiä
armoittamaan Intiaa mahtavilla kutomatehtailla! Tämä olisi samaa
kuin mennä turmelemaan toisten Dharmaa. Omien tuotteiden
maastavienti on yhtä rikollista kuin vieraiden tuotteiden
maahantuonti. Sillä »proselytismi (käännytyskiihko) on Swadešin
periaatteiden vastainen». Ja tämän lain johdonmukainen seuraus
(vaikkakin eurooppalaisille yllättävä) on, ettei pidä viedä maasta
enempää tuotteita kuin ajatuksiakaan.

Seikka, että Intian arvo historian kuluessa on kovasti laskenut,


pohjautuu sen Egyptin ja Rooman kanssa kauppaa käyneiden esi-
isien rikokseen, joka rikos yhä on uudistunut kaikkien seuraavien
sukupolvien aikana. Jokainen maa, jokainen kansanluokka pysyköön
omassa kutsumuksessaan, eläköön omista apulähteistään ja
perintätavoistaan!

Välttäkäämme olla läheisessä kanssakäymisessä niiden kanssa,


joiden yhteiskuntatavat ovat erilaiset kuin meidän. Olkaamme
kietomatta elämäämme sellaisten ihmisten ja kansojen elämään,
joiden ihanne on ristiriidassa meidän ihanteemme kanssa…
Jokainen ihminen on puro. Jokainen kansa on virta. Niiden tulee
seurata uomaansa kirkkaina ja tahrattomina kunnes saavuttavat
autuuden meren, jossa ne kaikki sekaantuvat.»

Tämä on natsionalismin voittoa. Kaikkein puhtainta. Kaikkein


ahtainta. On jäätävä kotiin. Suljettava kaikki ovet. Ei vaihdettava
mitään. Kaikki säilytettävä. Ei myytävä mitään. Ei mitään ostettava.
On puhdistuttava. Luostarimunkkien keskiaikaista evankelismia.[76]
Ja laajasydäminen Gandhi antaa tähän nimensä.

Ymmärtää kyllä Tagoren harmin näiden taantuvan natsionalismin


pappien takia, jotka pyrkivät seisauttamaan vuosisatain kulun,
sulkemaan häkkiin hengen innon ja katkaisemaan kaikki sillat
Länteen.[77] Todellisuudessa tämä ei ole ollenkaan Gandhin ajatus.
Hän kirjoittaa suorat sanat Tagorelle: »Swadeši on sanoma
maailmalle.» (Siis hän välittää maailmasta eikä hylkää
»proselytismiä, käännytyskiihkoa».) »Pois yhteistoiminta» -liike ei ole
suunnattu Länttä vastaan. Se on suunnattu aineellista sivistystä ja
sitä seuraavaa heikkojen riistämistä vastaan.» (Siis hän taistelee
ainoastaan Lännen erheitä vastaan, työskentelee Lännen
hyväksikin). »Se on pako omaan itseemme», (mutta väliaikainen
pako, kootaksemme voimiamme ja asettaaksemme ne sitten
ihmisyyden palvelukseen). »Intian tulee oppia elämään, ennenkuin
oppii kuolemaan ihmisyyden puolesta…» Eikä Gandhi kiellä
mitenkään yhteistoimintaa eurooppalaisten kanssa, ehdolla, että he
sopeutuvat terveelliseen ihanteeseen, jota hän kaikille tarjoaa.

Tämä Gandhin sisin ajatus on suunnattomasti laajempi,


inhimillisempi, yleismaailmallisempi[78] kuin hänen lippunsa eli
julistettu Evankeliumi. Miksi hän siis on antanut siihen nimensä?
Miksi hän sallii sulkea suurenmoisen ihanteensa, joka tarjoutuu koko
maapallolle, intialaisen teokratian (jumalaisvallan) ahtaisiin rajoihin?
Hirvittäviä oppilaita! — Mitä puhtaampia ne ovat, sitä turmiollisempia
ne ovat. Jumala varjelkoon suurta miestä ystävistään, jotka
käsittävät vain osan hänen ajatuksestaan! Tekemällä niistä
lakikokoelman he hävittävät sopusoinnun, joka on hänen elävän
sielunsa pääasiallisin avu!

Tässä ei vielä kaikki. Ainakin ne, jotka elävät aivan lähellä


Mestaria, hänen suoranaiset oppilaansa, kantavat yhä hänen
siveellisen jaloutensa leimaa. Mutta mitä säilyttävät ne, jotka ovat
oppilaiden oppilaita, — ja muut, kansat, joille saapuu vain
vääristettyjä kaikuja hänen sisäisen puhdistumisensa ja luovan
kieltäymyksensä opista? Ulkonaisimman, aineellisimman seikan:
Swarâjin (Home Rulen) messias-tehtävän ja rukin. Tämä on
edistyksen kieltämistä. Fuori Barbari! Tagore on syystä levoton
väkivallan johdosta, jota »pois väkivalta» -liikkeessä apostolit (eikä
Gandhi itsekään ole siitä vapaa) osoittavat ei ihmisiä, vaan Lännen
asioita kohtaan. Gandhi kyllä sanoo, että »hän peräytyisi taistelusta,
jos tuntisi vihaa englantilaisia kohtaan», että tulee rakastaa niitä,
joita vastaan taistelee ja että tulee vihata vain vääryyksiä, »vihata
saatanallisuutta, rakastaen kuitenkin Saatanaa.» Mutta tämä on
hyvin pulmallista puhetta kansan ymmärrykselle. Kun jokaisessa
kongressissa liikkeen johtajat muistuttavat intohimoisesti
englantilaisten rikoksista ja heidän vilpistään, Punjabin murhista ja
Khilafatista, kasautuu vihaa patojen taa, ja voi onnettomuutta, kun
pato murtuu! Kun Gandhi johtaa Bombayssa kalliiden kankaiden
polttoa elokuussa 1921 ja vastaa Tagoren ystävän Andrewsin
haikeisiin soimauksiin Hävityksen etiikallaan, hän uskoo
kääntävänsä kansan vihan ihmisistä asioihin. »Mutta hän ei huomaa,
että kansan viha kulkee omia uomiaan, vaan ajattelee: »Ensin asiat!
Sitten ihmiset!» Eikä hän aavista, että samassa Bombayssa, ei täyttä
kolmea kuukautta myöhemmin, kansa tappaa ihmisiä. Hän on liian
pyhä, liian puhdas, liian vapaa ihmisessä piilevistä intohimoista. Hän
ei kyllin muista intohimojen piilevän niissä, jotka häntä kuuntelevat ja
ahmivat hänen sanojaan. Selvänäköisempi Tagore huomaa »pois
yhteistoiminta» -ihmisten varomattomuuden, kun he kaikessa
viattomuudessaan lakkaamatta muistuttavat Euroopan tekemistä
vääryyksistä, julkisesti opettavat »pois väkivaltaa», istuttaen kansan
henkeen kuumeen myrkyn, joka vie väkivaltaan. He eivät sitä epäile,
he, apostolit, jotka eivät tunne mitään väkivaltaa sydämessään!
Mutta sen, joka ohjaa toiminnan asiaa, tulee kuunnella muiden
sydämiä eikä omaansa. Varokaa kansaa! Cave canem! Gandhin
kaltaisen henkilön siveelliset käskyt eivät riitä pitämään sitä aisoissa.
Ehkä ainut mahdollisuus asian onnistumiseen olisi se, että he
tottelisivat horjahtamatta johtajan ankaraa kuria; se, että johtaja
suostuisi olemaan Jumala, mihin häntä salaisesti kiihoittavat ne,
jotka häntä jo esittävät Šri-Krišnana. Mutta Gandhin vilpittömyys ja
hänen vaatimattomuutensa ovat siihen esteenä.

Siis jää ainoastaan mitä puhtaimman ihmisen yksinäinen ääni


liitelemään ihmisvaltameren pauhun yllä. Kuinka kauan onnistuu sen
saada itsensä kuulumaan? Suurenmoinen ja surullinen odotus!
IV.

Koko vuosi 1921, jolloin toiminta kiihtyy, on täynnä epävarmuutta ja


tuimia vastuksia. Gandhi ei jää syrjään niiden heilahteluilta.

Kapina nousi, ja hallituksen raa'at pakkotoimenpiteet kiirehtivät


sen rytmiä. Malegaonissa, Nasikin alueella puhkeaa verisiä
kahakoita, Giridihissä Beharissa meteleitä. Toukokuun alussa 1921
on vakavampia näytöksiä Assamissa, jossa kaksitoistatuhatta kulia
jätti työnsä teeistutuksilla. Itäisessä Bengaalissa rautateiden ja
laivojen työväki tekee täydellisen kaksikuukautisen lakon,
pannakseen vastalauseen. Gandhi koettaa vielä näytellä sovittajan
osaa; hänellä on toukokuussa pitkä kohtaus varakuninkaan, lordi
Readingin kanssa; hän tarjoo tälle välitystä Ali-veljesten suhteen,
joita syytettiin väkivaltaan yllyttävistä puheista; hän saa moslemi-
ystäviltään nimenomaisen julistuksen, etteivät he koskaan tule
turvautumaan väkivaltaan.

Mutta liikkeen voima ei tästä vähentynyt; ja Intian muhamettilainen


väestö tekee jatkuvasti mitä uskaliaimpia yrityksiä. Heinäkuun 8 p:nä
Karachissa koko Intian Khilafatin konferenssi uusii Islamin
vastalauseet, selittäen moslemille olevan laitonta palvella armeijassa
tai auttaa sotaväenotossa ja uhaten Englannin hallitukselle, mikäli se
taistelee Angoran hallitusta vastaan, julistavansa koko Intian
kongressin loppuvuoden istunnossa siviilitottelemattomuuden ja
Intian tasavallan. — Heinäkuun 28 p:nä Intian kongressin komitea,
kokoontuneena Bombayhin (ensimmäinen uuden perustuslain
jälkeen valittu komitea), säätää, että kaikkien velvollisuus on kylmästi
kohdella Walesin prinssiä, jota odotettiin pian Intiaan, päättää
täydellisen ulkolaisten kankaiden vieromisen ennen syyskuun 30
p:ää, rohkaisee ja säännöstelee kansallista kehruuta ja kudontaa,
kiihoittaa taistelua juomia vastaan välittämättä hallituksesta, joka
suojelee vähittäiskauppiaita. Mutta Khilafatin moslemeja
viisaampana se moittii meteleitä ja neuvoo luopumaan tällä hetkellä
siviilitottelemattomuudesta, samaan aikaan kuitenkin levittäen
propagandaa »pois väkivalta».

Elokuussa pääsee valloilleen moplahsien raaka meteli, joka


kestää useamman kuukauden. Gandhi tahtoo mennä Maulana
Mohamed Alin kanssa Kalkuttasta Malabariin sitä rauhoittamaan.
Hallitus ei sitä salli ja pidätyttää syyskuussa Maulana Mohamedin ja
hänen veljensä Maulana Shaukat Alin ja useita huomattavia
moslemeja siviilitottelemattomuuden ehdotuksista, joista äänestettiin
Khilafatin konferenssissa. Khilafatin keskuskomitea Delhissä toistaa
heti Khilafatin päätöksen, jota vahvistavat voimallisesti sadat
kokoukset. Lokakuun 4 p:nä Gandhi julistaa itsensä solidaariseksi
moslemiveljiensä kanssa. Kongressin viidenkymmenen tunnetun
nimen tukemana hän julkaisee manifestin, joka vaatii takaisin
jokaiselle kansalaiselle oikeutta lausua mielipiteensä, ottaako vai ei
osaa hallitukseen, teroittaa, miten jokaiselle intialaiselle on
sopimatonta palvella, olkoonpa siviilivirkamiehenä tai sotilaana,
hallitusta, joka on aikaansaanut Intian siveellisen, taloudellisen ja
valtiollisen rappeutumisen, ja julistaa jokaisen velvollisuudeksi siitä
eroamisen. Ali-veljesten oikeusjuttu tapahtuu Karachissa. Heidät
tuomittiin syytettyjen tovereittensa kera kahden vuoden ankaraan
vankeuteen. Intia kostaa yhä tarmokkaammin. Gandhin manifestin
vahvistaa marraskuun 4 p:nä koko Intian kongressin komitea
Delhissä. Komitea ottaa päättävän askeleen; se valtuuttaa joka
maakunnan omalla vastuullaan ryhtymään siviilitottelemattomuuteen,
alkaen verojen maksun lopettamisesta. Se panee ehdoksi, että
vastustavien ensin täytyy antaa laillinen todistuskirja täydellisestä
Swadešin ja »pois yhteistoiminta» -ohjelman hyväksymisestä, siihen
luettuina käsinkehruu ja »pois väkivalta» -aatteen todellinen
velvoitus. — Se koettaa täten Gandhin johdolla sovittaa kapinaa
kurin ja uhrautuvaisuuden lain kanssa. Tätä alleviivatakseen se
ilmoittaa siviilivastustajille ja heidän perheilleen, ettei heidän pitäisi
luottaa kongressin rahalliseen apuun.

Suuri boikottaus alkoi heti, kun Walesin prinssi marraskuun 17


p:nä nousi Bombayssa maihin. Kylmäkiskoisuuden käskyä
seurasivat keski- ja aliluokat. Rikkaat, parsit, julkiset henkilöt eivät
siitä välittäneet. Rahvas pahoinpiteli heitä säästämättä naisia, ja
meteli syttyi nopeasti; taloja ryöstettiin, yltympäri oli haavoittuneita ja
tapettuja. Tämä oli ainoa räikeä purkaus koko Intiassa, jossa
määrättyä Hartalia (juhlallinen lakko) uskonnollisesti noudatettiin,
rauhassa, ilman välikohtauksia. Mutta Gandhi oli sen takia sanainsa
mukaan »kuten nuolen lävistämä». Ensimmäisen uutisen saapuessa
meteleistä hän kiiruhti niihin paikkoihin, joissa metelöijät
ihastushuudoin vastaanottivat hänet; hänen häpeänsä kasvoi siitä
kahta suuremmaksi. Hän nuhteli ankarasti kansaa ja käski sitä
hajautumaan. Hän sanoi, että parseilla oli oikeus juhlia prinssiä
halunsa mukaan ja ettei mikään voinut selittää inhottavia
väkivaltaisuuksia. Kansanjoukko vaikeni, mutta myöhemmin
selkkaukset syttyivät uudelleen. Pahimmat ainekset olivat nousseet
maasta; kaksikymmentätuhatta kapinassa olevaa miestä ei heti anna
itseänsä palauttaa järkiin. Meteli pysyi kuitenkin rajoitettuna;
pieninkin eurooppalainen vallankumouspäivä jättää enemmän
hävitystä. Gandhi lähetti Bombayn asukkaille ja »pois
yhteistoiminta»-ihmisille lohduttomia vetoamisia, jotka
sanomalehdistö julkaisi. Hän selitti, että sellaiset näytökset tekivät
tällä haavaa mahdottomaksi joukkosiviilitottelemattomuuden, ja hän
lykkäsi sen täytäntöönpanon toistaiseksi. Itseään rangaistakseen
muiden väkivaltaisuuksista hän määräsi itselleen uskonnollisen
paaston kahdeksi kymmeneksi tunniksi viikossa.

Intian eurooppalaisia eivät kuitenkaan Bombayn selkkaukset


tehneet siinä määrin levottomiksi kuin Hartalin mieltäjärkyttävä
yksimielisyys kautta koko Intian. He kiirehtivät varakuningasta
toimimaan. Maakuntien hallitukset ryhtyivät moniin
väkivaltaisuuksiin, jotka menivät ulkopuolelle laillisuuden. Vedettiin
uudelleen esiin vanha laki anarkisteja ja salaisia seuroja vastaan
vuodelta 1908; sitä käytettiin kongressin ja Khilafatin vapaaehtoisten
yhdistyksiä vastaan. Tuhansia pidätyksiä tehtiin. Seuraus: tuhansia
uusia vapaaehtoisia kirjoittautui julkisiin luetteloihin. Maakuntien
komiteoille annettiin määräys järjestää vapaaehtoisjoukot ja määrätä
näille yhtenäinen kuri. Hartal määrättiin joulukuun 24 p:ksi, prinssin
Kalkuttaan tulon päiväksi. Ja sanottuna päivänä prinssi kulki läpi
aution Kalkutan.

Näinä hetkinä, joissa tuntui piilevän vallankumousta, avattiin


Ahmedabadissa koko Intian kansalliskongressi. Sillä oli vuoden 1789
säätykokouksen liikuttava juhlallisuus. Presidentti oli juuri vangittu.
Keskustelut olivat lyhyitä. Kongressi vahvisti uudelleen »pois
yhteistoiminta» -opin, vaati kaikkia kansalaisia tarjoutumaan
»vapaaehtoisiksi», mikä merkitsi pidättämistä, kehoitti Intian kansaa
pitämään kaikkialla kokouksia, julisti uskoansa
siviilitottelemattomuuteen, jonka voima on yhtä suuri ja ihmisyys
suurempi kuin asestetun kapinan; ja se neuvoi järjestämään
siviilitottelemattomuuden heti kun joukko tulisi kyllin opastetuksi
»pois väkivalta» -aatteen toimintatavoissa. Aavistaen suurimman
osan jäsenistään joutuvan vangeiksi istunnon lopussa kongressi
antoi Gandhille kaiken valtansa: teon diktatuurin ja oikeuden valita
seuraajansa; se jätti hänet yksikseen Intian politiikan johtajaksi, sillä
ainoalla ehdolla, ettei hän saa muuttaa kansallista credoa eikä tehdä
rauhaa hallituksen kanssa ilman kongressin komitean suostumusta.
Kokouksen osanottajista yksi osa oli jättänyt erään ehdotuksen, joka
tähtäsi väkivaltaiseen toimintaan, jotta saavutettaisiin mitä pikimmin
Intian täydellinen riippumattomuus. Enemmistö sen hylkäsi, pitäen
kiinni Gandhin periaatteista.

Seuraavina viikkoina ilmeni Intiassa yleinen uskonnollinen


innostus. 25.000 miestä ja naista tarjoutui riemulla vankeuteen.

Heidän jälessään tuhannet muut nousivat, odottaen vuoroansa,


voidakseen osoittaa uskoaan. Uudemman kerran Gandhi
valmistautui antamaan määräyksen siviilitottelemattomuuteen.
Merkki oli annettava mallimaasta, missä hänen ajatuksensa oli aina
löytänyt valiomaaperän: Bardolista, Bombayn maakunnasta.[79]
Gandhi ilmoittaa sen varakuninkaalle helmikuun 9 p:nä 1922
julkisella kirjeellä, joka on kohtelias, mutta todellinen sodanjulistus.
Hän on, hän sanoo, liikkeen vastuunalainen johtaja. Bardoli on Intian
joukkokapinan ensimmäinen liittymä hallitusta vastaan, joka on
raa'asti hyökännyt sananvapauden, yhdistys- ja painovapauden
kimppuun. Gandhi suo lordi Readingille seitsemän päivää
armonaikaa politiikan muutokseen. Ellei hän sitä tee, on käsky
annettu: kapina alkaa.[80]
Varakuninkaalle osoitettu kirje oli juuri lähtenyt, kun edellisiä
verisempi näytelmä näyteltiin Chauri-Chaurassa, Gorakhpurin
alueella. Erään kulkueen aikana poliisit olivat hyökänneet kansan
kimppuun. Kun heitä vastaan vuorostaan hyökättiin, he avasivat
tulen ja pakenivat Thanaan.[81] Rahvas sytytti sen tuleen. Turhaan
piiritetyt pyysivät armoa, heidät surmattiin ja poltettiin. Provokatismi
oli alkanut heidän puoleltaan eikä heidän murhaansa yksikään »pois
yhteiskunta» -liikkeen vapaaehtoinen ollut ottanut osaa. Gandhilla oli
siis oikeus vapautua vastuunalaisuudesta. Mutta hänestä oli todella
tullut Intian omatunto. Yhdenkin intialaisen rikos koski häneen
verisesti. Hän otti päälleen kaikki kansansa synnit. — Hänen
järkytyksensä oli niin suuri, että hän seisautti toisen kerran liikkeen,
jonka hän juuri oli määrännyt alkavaksi. Tilanne oli paljon tukalampi
tällä kertaa kuin Bombayn metelin jälkeen. Hän oli muutamaa päivää
aikaisemmin lähettänyt ultimaattuminsa varakuninkaalle. Miten voida
se peruuttaa tulematta naurettavaksi? Ylpeys, »saatana», kuten hän
sanoi, kielsi häntä. Tämä oli yksi syy lisää, miksi hän sen kumminkin
päätti. Helmikuun 16 p:nä 1922 ilmestyy Young Indiassa yksi tämän
elämän ihmeellisimpiä todistuskirjoja, hänen mea culpa'nsa, julkinen
tunnustuksensa. Itsesolvauksen pohjalta nouseva ensimmäinen
puhe on riemuitsemista ja kiitosta Jumalalle, joka on hänet
nöyryyttänyt!

»Jumala on ollut minulle ylenpalttisen hyvä. (God has been


abundantly kind to me). Kolmannen kerran on hän minulle
ilmoittanut, ettei Intialla ole vielä sitä »pois väkivalta» -aatteen ja
totuuden ilmapiiriä, joka voi, joka yksin voi oikeuttaa
joukkosiviilitottelemattomuuden, ainoan kyllin arvokkaan kantamaan
siviilitottelemattomuuden nimeä, s.o. lempeän, nöyrän, viisaan,
vapaaehtoisen ja kuitenkin rakastavan, ei koskaan rikollisen eikä
vihamielisen. Hän ilmoitti sen minulle ensi kerran 1919, kun alkoi
kiihoitus Acte Rovvlattia vastaan. Ahmedabad, Viramgam ja Kheda
ovat erehtyneet. Amritsar ja Kasur ovat erehtyneet. Olen tullut
järkiini, olen kutsunut erehdystäni himalayalaiseksi laskuvirheeksi,
olen nöyrtynyt Jumalan ja ihmisten edessä, olen pysäyttänyt ei
ainoastaan joukkosiviilitottelemattomuuden, vaan omanikin… Toisen
kerran se tapahtui Bombayn tapahtumain yhteydessä. Jumala pani
minut niiden silminnäkijäksi… Pysäytin joukkotottelemattomuuden,
jonka piti alkaa Bardolissa. Nöyryytys oli suurempi, mutta se teki
minulle hyvää. Olen varma, että kansa on voittanut tästä
siirtämisestä. Täten Intia on pysynyt totuuden ja »pois väkivalta» -
aatteen edustajana. Mutta katkerin nöyryytys on tämänpäiväinen…
Jumala on puhunut selvästi Chauri-Chauran kautta… Hetkellä, jolloin
Intia pyrkii nousemaan vapauden valtaistuimelle »pois väkivalta» -
aatteen avulla, rahvaan väkivalta on surullisena enteenä… »Pois
yhteistoiminta» -miesten tulee pitää silmällä maan väkivaltaisuutta.
Se on mahdollista vain siten, että Intian »huligaanit» kukistetaan…

Hän kutsui kokoon helmikuun 11 p:nä Bardoliin kongressin


toimintakomitean, jolle hän ilmaisi levottomuutensa. Useat hänen
virkaveljensä eivät olleet samaa mieltä hänen kanssaan. Mutta
taivas oli hänet »siunannut», hän sanoo, »koska hän löysi heissä
niin paljon sääliväisyyttä ja kunnioitusta. He ymmärsivät hänen
epäilyksensä ja suostuivat hänen vaatimuksestaan lykkäämään
siviilitottelemattomuuden pyytäen kaikkia järjestöjä luomaan »pois
väkivalta» -ilmapiirin.

»Minä tiedän», lausuu Gandhi, »että tämä näyttää liian vähän


viisaalta politiikalta; mutta tämä on uskonnon kannalta
ymmärrettävissä. Maa hyötyy minun nöyryytyksestäni ja erheeni
tunnustuksesta. Ainoat hyveet, joihin luotan, ovat totuus ja »pois
väkivalta». En vaadi mitenkään yli-inhimillistä. En siitä välitä. Kannan
samaa lahoavaa lihaa kuin heikoimmat ja olen niinikään
erehtyväinen. Minun palveluksillani on paljon rajoituksia; mutta
Jumala on tähän saakka niiden vaillinaisuudesta huolimatta niitä
siunannut. Erehdyksen tunnustaminen on luudan sipaisu. — Tunnen
itseni voimakkaammaksi tehtyäni tunnustuksen, ja asian tulee hyötyä
takaisinkimmahduksestaankin. Ei ihminen ole koskaan saavuttanut
päämääräänsä ollessaan itsepäinen oikealta tieltä
poiketessaankin… Minulle sanotaan vastaan, ettei Chauri-Chaura -
rikoksella ole mitään tekemistä Bardolin suunnitelmain kanssa. En
sitä ollenkaan epäile. Bardolin kansa on mielestäni Intian
rauhaarakastavinta. Mutta Bardoli on vain yksi piste. Sen ponnistus
voi onnistua vain silloin, kun sillä on täydellinen yhteisymmärrys
Intian muiden osien kanssa… Arsenikkihiukkanen maitoastiassa
myrkyttää maidon… Chauri-Chaura on kuin kuolettava myrkky… Se
ei ole ainoa eikä eristetty. Se kuuluu sinne tänne levinneisiin rahvaan
väkivaltaisuuden ikäviin satunnaisiin symptoomeihin… Oikea
siviilitottelemattomuus ei siedä mitään kiihoitusta. Se on valmistusta
mykkään kärsimykseen. Sen vaikutus on ihmeellinen, vaikka
tuntumaton ja lempeä… Chauri-Chauran murhenäytelmä on
osoittava sormi tiellämme. Ellemme halua väkivaltaisuuden
nousevan »pois väkivallasta», meidän on kiireesti tultava järkiimme,
muodostettava rauhan ilmapiiri, oltava uneksimatta
joukkotottelemattomuuden alkamista, ennenkuin ollaan varmat, että
rauha säilytetään kaikesta huolimatta… Syyttäköön vastustaja meitä
pelkuruudesta! On suurempiarvoista olla väärin tuomittu kuin pettää
Jumala…»

Apostoli tahtoo sovittaa toisten vuodattaman veren.

»Minun täytyy elää henkilökohtainen puhdistus. Minun tulee kyetä


paremmin merkitsemään muistiin keveinkin muutos siveellisessä
ilmapiirissä ympärilläni.[82] Rukoukseni tulee olla todellisempi ja
nöyrempi. Ei mikään puhdista niinkuin tosi paasto; sen kautta
saavuttaa ihminen täydellisemmän itsensä, hengen ylivallan lihan
yli…»

Hän määrää itselleen julkisesti jatkuvan viiden päivän paaston.


Älköön kukaan sitä rajoittako. Hänen täytyy itse rangaista itsensä.
Hän on ollut taitamaton kirurgi. Hänen on joko jätettävä kaikki tai
saatava varmempi kokemus. Hänen paastonsa on samalla kertaa
katumusta ja rankaisua sekä itsensä että niiden Chauri-Chauran
asukkaiden takia, jotka ovat rikkoneet, ehkä hänen nimensä
huulillaan. Gandhi haluaisi yksin kärsiä heidän puolestaan; heitä hän
neuvoo antautumaan hallitukselle ja tunnustamaan. Sillä he ovat
tehneet hirvittävän karhunpalveluksen asialle, jota he tahtoivat
palvella.

»Haluaisin kärsiä kaikki nöyryytykset, kaikki kidutukset, täydellisen


ostrakismin, jopa kuolemankin, jos vain voisin ostaa liikkeemme
tulemasta väkivallaksi tai väkivallan edelläkävijäksi…»

*****

Ihmisomantunnon historiassa on vähän yhtä yleviä sivuja.


Sellaisen työn siveellinen arvo on poikkeuksellinen. Poliittisena
tekona se on suorastaan hämmästyttävä. Gandhi tunnusti itse, että
häntä voitiin pitää »poliittisesti mielettömänä eikä tarpeeksi
viisaana.» On vaarallista jännittää kansan kaikki jouset, panna se
huohottamaan määrätyn teon odotusta, nostaa käsi määräyksen
antoon ja sitten, kun kauhea kone jo järisee, kolme kertaa se
pysähdyttää. On vaara, että ratastot kuluvat ja into katkeaa.
Kun Kongressin Komitea kokoontui Delhissä helmikuun 22 p:nä
1922, Gandhi sai suuren vastarinnan jälkeen hyväksytyksi
Bardolissa 11 p:nä tehdyt päätökset. Syntyi skisma »pois
yhteistoiminta»-miesten kesken. Gandhi tahtoi järjestäydyttävän
ankarammin, ennenkuin ryhdyttiin toimiin; ja hän esitti
järjestelysuunnitelman. Mutta moni vihastui tästä hitaudesta, pani
vastalauseen kapinamääräyksen lykkäämistä vastaan ja väitti, että
maan into näin tukahdutettiin. Osa halusi äänestää sensuuria
toimeenpanevalle komitealle ja esitti komitean määräykset
peruutettaviksi. Gandhi pääsi kuitenkin voitolle. Mutta hän kärsi
syvästi. Eipä enemmistökään, joka häntä laumana seurasi, tuottanut
hänelle paljoa iloa. Hän tunsi, ettei se ollut vilpitön. Ja usea hänen
puolestaan äänestänyt kutsui häntä »diktaattoriksi». Pohjaltaan hän
tunsi olevansa eri mieltä maansa kanssa. Hän sanoo sen uljaalla
suoruudellaan maaliskuun 2 p:nä 1922:

»Enemmistössä on niin paljon peitettyjä väkivaltavirtauksia,


tietoisia tai tiedottomia, että olen rukoillut onnettoman häviön
puolesta. Olen aina ollut vähemmistössä. Etelä-Afrikassa aloin
yksimielisyydellä, vajosin 64 hengen, jopa 16:n vähemmistöön ja
nousin uudelleen suunnattomaan enemmistöön. Parhain ja vakavin
työ tehtiin vähemmistön erämaassa… Pelkään enemmistöä. Minua
ellottaa arvostelemattoman joukon ihailu. Tuntisin maan
vankemmaksi jalkaini alla, jos he sylkisivät päälleni… Eräs ystäväni
kielsi minua väärin käyttämästä diktatuuriani… Kaukana siitä, että
olisin sitä tehnyt, kysyn pikemmin, enkö itse itseäni salli
»väärinkäyttää»! Tunnustan pelkääväni sitä enemmän kuin koskaan.
Ainoa pelastukseni on häpeämättömyydessäni. Olen ilmoittanut
ystävilleni Kongressissa olevani parantumaton. Joka kerta, kun
kansa tekee hairahduksia, tulen heitä jatkuvasti ripittämään. Ainoa
tyranni, jonka tunnustan tässä maailmassa, on sisällämme oleva
omantunnon ääni (the still small voice). Ja vaikka minun pitäisi
nähdä edessäni yhden ainoan hengen vähemmistö, minulla olisi
kuitenkin rohkeutta kuulua tähän epätoivoiseen vähemmistöön. Se
on ainoa vilpitön puolue. Olen tänään surullisempi ja luullakseni
viisaampi ihminen. Näen, että »pois väkivalta» -aatteemme on vain
pölyä. Palamme harmista. Hallitus vain lisää tulta mielettömillä
teoillaan. Voisi melkein sanoa sen haluavan nähdä tämän maan
murhien, tulipalojen, ryöstöjen raatelemana voidakseen väittää, että
se yksin kykenee ne sammuttamaan. »Pois väkivalta»-liikkeemme
on mielestäni syntynyt heikkoudestamme: ikäänkuin sydämissämme
hyväilisimme halua kostaa heti kun siihen olisi tilaisuutta. Voiko
vapaaehtoinen »Pois väkivalta» nousta tästä heikkojen pakotetusta
»Pois väkivallasta?» Eikö nykyhetken harrastukseni ole vain turhaa
kokeilua?… Ja jos raivon puhjetessa yksikään ei jäisi syrjään, jos
jokaisen käsi nousisi lähimmäistään vastaan, mitä hyödyttäisi silloin,
että minä paastoan, kuollakseni sellaisen onnettomuuden jälkeen?…
Jollette kykene »pois väkivaltaan», hyväksykää rehellisesti väkivalta!
Mutta ei ulkokultaisuutta![83] Enemmistö vaatii »pois väkivalta»
aatteen hyväksymistä… Tuntekoon se vastuunalaisuutensa! Sen
pitää nyt lykätä siviilitottelemattomuus ja tehdä ensinnä rakentavaa
työtä… Jollei, hukumme vesiin, joiden syvyyksiä emme aavista…»

Ja kääntyen vähemmistön puoleen hän sanoo sille:

»Te ette halua pois väkivaltaa»? Poistukaa Kongressista!


Muodostakaa uusi puolue! Lausukaa julkisesti credonne! Valitkoon
maa välillämme!… Mutta ei kaksimielisyyttä! Olkaa suorat!…»

Näissä nasevissa sanoissa on katkera, joskin miehekäs


surumielisyys. Oli Olivipuistojen yö. Gandhin vangitseminen oli
lähellä… Kuka tietää, vaikka hän sisimmässä sydämessään olisi
ottanut tapauksen vastaan vapautuksena?…

Hän oli sitä odottanut jo kauan. Marraskuun 10:nnestä päivästä


1920 lähtien hän oli ryhtynyt kaikkiin varokeinoihin. Hän oli sanellut
kansalle määräyksensä sen päivän varalta, jolloin hän ei enää olisi
heidän keskellään (If I am arrested). Hän palaa siihen uudessa
kirjoitelmassaan maaliskuun 9 p:ltä 1922, kun huhu hänen
vangitsemisestaan alkoi levitä. Hän ei sano pelkäävänsä
minkäänlaista hallituksen väkivaltaa. Hän pelkää vain yhtä seikkaa:
kansan väkivaltaisuuksia. Ne häpäisisivät hänet. »Pitäköön kansa
vangitsemisen! päivää ilon päivänä! Hallitus luulee, että Gandhin
tultua vangituksi Intian asia on lopussa. Osoittakaa sille, että
asianlaita on päinvastainen. Mitatkoon se kansan voiman!» Kaunein
kunnianosoitus, minkä kansa voi hänelle antaa, on se, että se
säilyttää täydellisen rauhan. Gandhia nöyryyttäisi ajatus, että hallitus
epäröi hänen vangitsemistaan verisen nousun pelossa. Siis
pysyköön kansa rauhallisena, älköön se jättäkö työtään, älköön
pitäkö kokouksia! Mutta sulkekoot oikeusistuimet ovensa, jätettäköön
hallituksen palveluspaikat, viralliset koulut olkoot autiot, toteutukoon
kokonaisuudessaan järjestyksen ja kurin vallitessa »pois väkivalta» -
ohjelma! Jos kansa toimii näin, on sillä voitto. Jollei, se sortuu.

Kun kaikki oli valmista, lähti Gandhi rakkaaseen turvapaikkaansa


Ašram de Sabarmatiin lähelle Ahmedabadia, siellä odottaakseen,
ajatuksiaan kooten rakastettujen oppilaiden keskuudessa
vangitsijainsa saapumista. Hän toivoi vankilaa. Hänen poissa
ollessaan Intian usko ilmaantuisi paremmin. »Ja hän, hän löytäisi
rauhan, jonka ehkä ansaitsi»…
Illalla maaliskuun 10 p:nä, vähän jälkeen rukouksen, poliisimiehet
saapuivat. Ašramiin oli ilmoitettu heidän tulonsa. Mahatma antautui
heidän käsiinsä. Matkalla vankeuteen hän tapasi Maulana Hasrat
Mohanin, muhamettilaisen ystävänsä, joka riensi kaukaa saapuville
juuri ajoissa häntä suudellakseen. Hänet saatettiin vankihuoneeseen
Young Indian toimittajan Bankerin kanssa. Hänen vaimollaan oli lupa
seurata häntä kynnykselle.

Lauantaina maaliskuun 18 p:nä kello kaksitoista alkoi »suuri


prosessi»[84] Ahmedabadin aluetuomarin ja tuomioistuimen edessä.
Se oli harvinaisen arvokas. Tuomari ja syytetty kilpailivat ritarillisessa
kohteliaisuudessa. Ei koskaan Englanti ole noussut taistelussa
jalomielisempään puolueettomuuteen. Tuomari, C.N. Broomsfield,
sovitti tänä päivänä paljon hallituksen virheitä. Gandhin ystävien
antama kertomus oikeudenkäynnistä julkaistiin osassa
eurooppalaista sanomalehdistöä, ja huhut siitä saapuivat Ranskaan.
Minä esitän sen siis ainoastaan lyhykäisesti.

Miksi hallitus oli päättänyt vangita Gandhin? Miten se oli kaksi


vuotta epäröityään voinut valita hetken, jolloin Mahatma oli juuri
suistanut kansansa kapinan ja näytti edelleenkin olevan väkivallan
välttäjä? Oliko tämä hairahdus? Vai tahtoiko se vahvistaa Gandhin
hirvittävän lauseen: »Hallitus näyttää tahtovan nähdä tämän maan
murhien, tulipalojen ja ryöstöjen raatelemana, saadakseen syyn sitä
masentaa!» — Todellisuudessa sen asema oli vaikea. Hallitus
kunnioitti ja epäili Gandhia. Se olisi tahtonut häntä säästää; mutta
Gandhi ei sitä puolestaan ollenkaan säästänyt. Mahatma paheksi
väkivaltaa; mutta hänen »pois väkivalta» -liikkeensä oli
vallankumouksellisempi kuin kaikki väkivalta. Niinä samoina päivinä,
jolloin hän nousi joukkosiviilitottelemattomuutta vastaan, Delhin
kongressin aattona, helmikuun 23 p:nä, hän oli julaissut yhden
brittiläiselle vallalle uhkaavimmista artikkeleistaan. Lordi
Birkenheadin ja Herra Montagun loukkaava sähkösanoma oli juuri
antanut Intialle korvapuustin.[85] Gandhi oli harmin pakahduttamana
nostanut uudestaan solvaisevan, taisteluvaatimuksen:

»Ei mitään sovittelua valtakunnan kanssa, niin kauan kuin


brittiläinen leijona ravistaa kasvojemme edessä verisiä kynsiään!…
Brittein valtakunta, joka on rakennettu maan ruumiillisesti
heikompain heimojen järjestetylle hyväksikäyttämiselle ja raa'an
voiman sovinnaiselle näytteilleasettamiselle, ei voi kestää, jos on
olemassa oikeamielinen Jumala maailman kaikkeutta hallitsemassa.
On jo koittanut aika, jolloin brittiläinen kansa käsittää vuonna 1920
aletuntaistelun olevan taistelua loppuun saakka, kestäköön se sitten
kuukauden, vuoden, kuukausia tai vuosia… Rukoilen Jumalaa
antamaan Intialle nöyryyttä ja tarpeeksi voimaa, jotta se jaksaisi
kestää ilman väkivaltaa loppuun saakka. Mutta on mahdotonta
alistua näihin julkeisiin taisteluvaatimuksiin…»

Syytös perustui tähän ja pariin uudempaan[86] kirjoitelmaan.


Gandhia syytettiin siitä, »että hän oli kehoittanut nurjamielisyyteen,
kiihoittanut vihaan ja yllyttänyt ylenkatsomaan lakien säätämää
Hänen Majesteettinsa hallitusta.» Hänellä ei ollut ollenkaan puoltajia.
Hän oli asiassa asianajajana ja samalla kaikkeen syyllisenä.

Yleinen asianajaja, sir J.T. Strangman Bombaysta, kannatti sitä,


että syytöksen kolmea eri kohtaa ei käsiteltäisi erillisinä, vaan
oleellisina osina jo kaksi vuotta hallitusta vastaan käydystä
taistelusta, ja hän todisti sen lainauksilla. Hän myönsi Gandhin
suuret avut. Se paha, minkä tällaiset kirjoitukset voivat aikaansaada,
oli siitä syystä vain vakavampi. Hän pani Gandhin laskuun Bombayn
ja Chauri-Chauran veriset tapahtumat. Epäilemättä Gandhi saarnasi
»pois väkivaltaa», mutta samalla kertaa nurjamielisyyttä. Hän oli siis
vastuussa rahvaan väkivallantöistä.

Gandhi pyysi sananvuoroa. Hänen omantunnontaistelunsa, hänen


tuskansa, hänen viimeviikkoiset epäilynsä niiden ratkaisujen
oikeudesta, joita hänen oli täytynyt tehdä, ja niistä heijastuksista,
joita niillä täytyi olla hänen kansansa omaantuntoon, olivat
häipyneet. Hän oli saanut takaisin sielunsa tyynen herruuden. Hän
hyväksyi kaiken, mitä oli tapahtunut ja mitä vielä tapahtuisi
välttämättömyydestä, josta hän ehkä voisi olla pahoillaankin, mutta
jota hänen täytyi kantaa. — Hän selitti olevansa samaa mieltä
yleisen asianajajan kanssa. Niin, hän oli vastuunalainen! Täydelleen
vastuunalainen. Hän oli saarnannut nurjamielisyyttä jo paljon
kauemmin aikaa kuin syyte sanoi. Se oli hänen intohimonsa. Hän otti
päälleen kaiken solvauksen Madrasin levottomuuksista, Chauri-
Cauran »pirulliset rikokset» ja Bombayn »mielettömät
häväistykset»…

»Yleinen syyttäjä on oikeassa sanoessaan, että vastuunalaisena


ihmisenä, koska olen saanut hyvän kasvatuksen osakseni ja
saavuttanut suuren määrän tämän maailman kokemusta, minun olisi
pitänyt tietää tekojeni seuraukset. Tiesin leikkiväni tulella. Olen
antautunut vaaraan; ja jos minut vapautettaisiin, alkaisin uudestaan.
Olen tämän kypsäksi harkinnut näinä viimeisinä öinä. Tunsin tänä
aamuna, etten olisi tehnyt velvollisuuttani, jos olisin jättänyt
sanomatta, minkä nyt juuri sanon. Koetin ja koetan välttää
väkivaltaa. »Pois väkivalta» on uskoni ensimmäinen ja viimeinen
pykälä. Mutta minun oli valittava; — joko alistua poliittiseen
järjestelmään, joka mielestäni on tehnyt maalleni korjaamattoman
vahingon, — tai uskaltaa ottaa vastaan kansani mieletön raivo, sen
saadessa kuulla huuliltani totuuden. Tiedän kansani aina hetkittäin

You might also like