C Move Semantics The Complete Guide 1st Edition Nicolai M Josuttis Instant Download
C Move Semantics The Complete Guide 1st Edition Nicolai M Josuttis Instant Download
https://ebookbell.com/product/c-move-semantics-the-complete-
guide-1st-edition-nicolai-m-josuttis-46824864
https://ebookbell.com/product/c-move-semantics-the-complete-guide-
ebook-nicolai-m-josuttis-23272572
https://ebookbell.com/product/c-move-semantics-the-complete-guide-
nicolai-m-josuttis-46703930
https://ebookbell.com/product/every-move-you-make-cl-taylor-56470666
https://ebookbell.com/product/every-move-you-make-cl-taylor-57477872
China On The Move Migration The State And The Household 1st Edition C
Cindy Fan
https://ebookbell.com/product/china-on-the-move-migration-the-state-
and-the-household-1st-edition-c-cindy-fan-1634230
https://ebookbell.com/product/christians-on-the-move-the-book-of-acts-
henrietta-c-mears-38261912
https://ebookbell.com/product/medical-sociology-on-the-move-new-
directions-in-theory-1st-edition-william-c-cockerham-ed-4412034
https://ebookbell.com/product/overcoming-imposter-anxiety-move-beyond-
fear-of-failure-and-selfdoubt-to-embrace-your-worthy-capable-self-
ijeoma-c-nwaogu-53681510
https://ebookbell.com/product/overcoming-imposter-anxiety-move-beyond-
fear-of-failure-and-selfdoubt-to-embrace-your-worthy-capable-self-1st-
edition-ijeoma-c-nwaogu-56037458
Josuttis: C++ Move Semantics 2022/04/19 13:28 page i
Nicolai M. Josuttis
First Edition
Josuttis: C++ Move Semantics 2022/04/19 13:28 page ii
Nicolai M. Josuttis
This book was typeset by Nicolai M. Josuttis using the LATEX document processing system.
Contents
Preface xi
An Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Versions of This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
iii
Josuttis: C++ Move Semantics 2022/04/19 13:28 page iv
iv Contents
1.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Contents v
6 Moved-From States 89
6.1 Required and Guaranteed States of Moved-From Objects . . . . . . . . . . . . . . . . . . . . . 89
6.1.1 Required States of Moved-From Objects . . . . . . . . . . . . . . . . . . . . . . . . . 90
Josuttis: C++ Move Semantics 2022/04/19 13:28 page vi
vi Contents
Contents vii
viii Contents
Contents ix
Glossary 233
Index 237
Josuttis: C++ Move Semantics 2022/04/19 13:28 page x
Josuttis: C++ Move Semantics 2022/04/19 13:28 page xi
Preface
Move semantics, introduced with C++11, has become a hallmark of modern C++ programming. However, it
also complicates the language in many ways. Even after several years of support, experienced programmers
struggle with all the details of move semantics, style guides still recommend different consequences for
programming even of trivial classes, and we still discuss semantic details in the C++ standards committee.
Whenever I have taught what I have learned about C++ move semantics so far, I have said, “Somebody
has to write a book about all this,” and the usual answer was: “Yes, please do!” So, I finally did.
As always when writing a book about C++, I was surprised about the number of aspects to be taught, the
situations to be clarified, and the consequences to be described. It really was time to write a book about all
aspects of move semantics, covering all C++ versions from C++11 up to C++20. I learned a lot and I am
sure you will too.
An Experiment
This book is an experiment in two ways:
• I am writing an in-depth book covering a complex core language feature without the direct help of a core
language expert as a co-author. However, I can ask questions and I do.
• I am publishing the book myself on Leanpub and for printing on demand. That is, this book is written
step by step and I will publish new versions as soon there is a significant improvement that makes the
publication of a new version worthwhile.
The good thing is:
• You get the view of the language features from an experienced application programmer—somebody who
feels the pain a feature might cause and asks the relevant questions to be able to motivate and explain the
design and its consequences for programming in practice.
• You can benefit from my experience with move semantics while I am still writing.
• This book and all readers can benefit from your early feedback.
This means that you are also part of the experiment. So help me out: give feedback about flaws, errors,
features that are not explained well, or gaps, so that we all can benefit from these improvements.
xi
Josuttis: C++ Move Semantics 2022/04/19 13:28 page xii
xii Preface
Acknowledgments xiii
Acknowledgments
First of all, I would like to thank you, the C++ community, for making this book possible. The incredible
design of all the features of move semantics, the helpful feedback, and their curiosity are the basis for the
evolution of a successful language. In particular, thanks for all the issues you told me about and explained
and for the feedback you gave.
I would especially like to thank everyone who reviewed drafts of this book or corresponding slides and
provided valuable feedback and clarification. These reviews increased the quality of the book significantly,
again proving that good things need the input of many “wise guys.” Therefore, so far (this list is still
growing) huge thanks to Javier Estrada, Howard Hinnant, Klaus Iglberger, Daniel Krügler, Marc Mutz,
Aleksandr Solovev (alexolut), Peter Sommerlad, and Tony Van Eerd.
In addition, I would like to thank everyone in the C++ community and on the C++ standards committee.
In addition to all the work involved in adding new language and library features, these experts spent many,
many hours explaining and discussing their work with me, and they did so with patience and enthusiasm.
Special thanks go to the LaTeX community for a great text system and to Frank Mittelbach for solving
my LATEX issues (it was almost always my fault).
And finally, many thanks go to my proofreader, Tracey Duffy, who has done a tremendous job of con-
verting my “German English” into native English.
Josuttis: C++ Move Semantics 2022/04/19 13:28 page xiv
xiv
This book teaches C++ move semantics. Starting from the basic principles, it motivates and explains all
features and corner cases of move semantics so that as a programmer, you can understand and use move
semantics correctly. The book is valuable for those who are just starting to learn about move semantics and
is essential for those who are using it already.
As usual for my books, the focus lies on the application of the new features in practice and the book will
demonstrate how features impact day-to-day programming and how you can benefit from them in projects.
This applies to both application programmers and programmers who provide generic frameworks and foun-
dation libraries.
xv
Josuttis: C++ Move Semantics 2022/04/19 13:28 page xvi
Initializations
I usually use the modern form of initialization (introduced in C++11 as uniform initialization) with curly
braces:
int i{42};
std::string s{"hello"};
This form of initialization, which is called brace initialization, has the following advantages:
• It can be used with fundamental types, class types, aggregates, enumeration types, and auto
• It can be used to initialize containers with multiple values
• It can detect narrowing errors (e.g., initialization of an int by a floating-point value)
• It cannot be confused with function declarations or calls
If the braces are empty, the default constructors of (sub)objects are called and fundamental data types are
guaranteed to be initialized with 0/false/nullptr.
Josuttis: C++ Move Semantics 2022/04/19 13:28 page xvii
Error Terminology
I often talk about programming errors. If there is no special hint, the term error or a comment such as
... // ERROR
means a compile-time error. The corresponding code should not compile (with a conforming compiler).
If I use the term runtime error, the program might compile but not behave correctly or result in undefined
behavior (thus, it might or might not do what is expected).
Code Simplifications
I try to explain all features with helpful examples. However, to concentrate on the key aspects to be taught,
I might often skip other details that should be part of code.
• Most of the time I use an ellipsis (“...”) to signal additional code that is missing. Note that I do not use
code font here. If you see an ellipsis with code font, code must have these three dots as a language feature
(such as for “typename...”).
• In header files I usually skip the preprocessor guards. All header files should have something like the
following:
#ifndef MYFILE_HPP
#define MYFILE_HPP
...
#endif // MYFILE_HPP
So, please beware and fix the code when using these header files in your projects.
Feedback
I welcome your constructive input—both negative and positive. I have worked very hard to bring you what
I hope you will find to be an excellent book. However, at some point I had to stop writing, reviewing, and
tweaking to “release the new revision.” You may therefore find errors, inconsistencies, presentations that
could be improved, or topics that are missing altogether. Your feedback gives me a chance to fix these issues,
inform all readers about the changes through the book’s website, and improve any subsequent revisions or
editions.
The best way to reach me is by email. You will find the email address at the website for this book:
http://www.cppmove.com
If you use the ebook, you might want to ensure to have the latest version of this book available (remember
it is written and published incrementally). You should also check the book’s Web site for the currently
known errata before submitting reports. In any case, refer to the publishing date of this version when giving
feedback. The current publishing date is 2022-04-19 (you can also find it on page ii, the page directly after
the cover).
Many thanks.
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 1
Part I
Basic Features of Move Semantics
This part of the book introduces the basic features of move semantics that are not specific to generic pro-
gramming (i.e., templates). They are particularly helpful for application programmers in their day-to-day
programming and therefore every C++ programmer using Modern C++ should know them.
Move semantics features for generic programming are covered in Part II.
1
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 2
Chapter 1
The Power of Move Semantics
This chapter demonstrates the basic principles and benefits of move semantics using a short code example.
std::vector<std::string> createAndInsert()
{
std::vector<std::string> coll; // create vector of strings
coll.reserve(3); // reserve memory for 3 elements
std::string s = "data"; // create string object
3
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 4
int main()
{
std::vector<std::string> v; // create empty vector of strings
...
v = createAndInsert(); // assign returned vector of strings
...
}
Let us look at the individual steps of the program (inspecting both the stack and the heap) when we compile
this program with a C++ compiler that does not support move semantics.
• First, in main(), we create the empty vector v:
std::vector<std::string> v;
which is placed on the stack as an object that has 0 as the number of elements and no memory allocated
for elements.
• Then, we call
v = createAndInsert();
where we create another empty vector coll on the stack and reserve memory for three elements on the
heap:
std::vector<std::string> coll;
coll.reserve(3);
The allocated memory is not initialized because the number of elements is still 0.
• Then, we create a string initialized with "data":
std::string s = "data";
A string is something like a vector with char elements. Essentially, we create an object on the stack
with a member for the number of characters (having the value 4) and a pointer to the memory for the
characters.1
After this statement, the program has the following state: we have three objects on the stack: v, coll,
and s. Two of them, coll and s, have allocated memory on the heap:2
1 Internally, strings also store a terminating null character to avoid allocating memory when they are asked for a C
string representation of their value with the member function c_str().
2 With the small string optimization (SSO), the string s might store its whole value on the stack provided the value is
not too long. However, for the general case, let us assume that we do not have the small string optimization or the
value of the string is long enough so that the small string optimization does not happen.
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 5
• The next step is the command to insert the string into the vector coll:
coll.push_back(s);
All containers in the C++ standard library have value semantics, which means that they create copies of
the values passed to them. As a result, we get a first element in the vector, which is a full (deep) copy of
the passed value/object s:
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 6
So far, we have nothing to optimize in this program. The current state is that we have two vectors, v and
coll, and two strings, s and its copy, which is the first element in coll. They should all be separate
objects with their own memory for the value, because modifying one of them should not impact any of
the other objects.
• Let us now look at the next statement, which creates a new temporary string and again inserts it into the
vector:
coll.push_back(s+s);
This statement is performed in three steps:
1. We create the temporary string s+s:
2. We insert this temporary string into the vector coll. As always, the container creates a copy of the
passed value, which means that we create a deep copy of the temporary string, including allocating
memory for the value:
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 7
3. At the end of the statement, the temporary string s+s is destroyed because we no longer need it:
Here, we have the first moment where we generate code that is not performing well: we create a copy
of a temporary string and destroy the source of the copy immediately afterwards, which means that we
unnecessarily allocate and free memory that we could have just moved from the source to the copy.
• With the next statement, again we insert s into coll:
coll.push_back(s);
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 8
This is also something to improve: because the value of s is no longer needed some optimization could
use the memory of s as memory for the new element in the vector instead.
• At the end of createAndInsert() we come to the return statement:
return coll;
}
Here, the behavior of the program becomes a bit more complicated. We return by value (the return type
is not a reference), which should be a copy of the value in the return statement, coll. Creating a copy
of coll means that we have to create a deep copy of the whole vector with all of its elements. Thus, we
have to allocate heap memory for the array of elements in the vector and heap memory for the value each
string allocates to hold its value. Here, we would have to allocate memory 4 times.
However, since at the same time coll is destroyed because we leave the scope where it is declared,
the compiler is allowed to perform the named return value optimization (NRVO). This means that the
compiler can generate code so that coll is just used as the return value.
This optimization is allowed even if this would change the functional behavior of the program. If we
had a print statement in the copy constructor of a vector or string, we would see that the program no
longer has the output from the print statement. This means that this optimization changes the functional
behavior of the program. However, that is OK, because we explicitly allow this optimization in the C++
standard even if it has side effects. Nobody should expect that a copy is done here, in the same way that
nobody should expect that it is not, either. It is simply up to the compiler whether the named return value
optimization is performed.
Let us assume that we have the named return value optimization. In that case, at the end of the return
statement, coll now becomes the return value and the destructor of s is called, which frees the memory
allocated when it was declared:
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 9
However, right after that, we no longer need the temporary return value and we destroy it:
Again, we create a copy of a temporary object and destroy the source of the copy immediately after-
wards, which means that we again unnecessarily allocate and free memory. This time it applies to four
allocations, one for the vector and one for each string element.
For the state of this program after the assignment in main(), we allocated memory ten times and released it
six times. The unnecessary memory allocations were caused by:
• Inserting a temporary object into the collection
• Inserting an object into the collection where we no longer need the value
• Assigning a temporary vector with all its elements
We can more or less avoid these performance penalties. In particular, instead of the last assignment, we
could do the following:
• Pass the vector as an out parameter:
createAndInsert(v); // let the function fill vector v
• Use swap():
createAndInsert().swap(v);
However, the resulting code looks uglier (unless you see some beauty in complex code) and there is not
really a workaround when inserting a temporary object.
Since C++11, we have another option: compile and run the program with support for move semantics.
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 11
std::vector<std::string> createAndInsert()
{
std::vector<std::string> coll; // create vector of strings
coll.reserve(3); // reserve memory for 3 elements
std::string s = "data"; // create string object
int main()
{
std::vector<std::string> v; // create empty vector of strings
...
v = createAndInsert(); // assign returned vector of strings
...
}
There is a small modification, though: we add a std::move() call when we insert the last element into
coll. We will discuss this change when we come to this statement. Everything else is as before.
Again, let us look at the individual steps of the program by inspecting both the stack and the heap.
• First, in main(), we create the empty vector v, which is placed on the stack with 0 elements:
std::vector<std::string> v;
• Then, we call
v = createAndInsert();
where we create another empty vector coll on the stack and reserve uninitialized memory for three
elements on the heap:
std::vector<std::string> coll;
coll.reserve(3);
• Then, we create the string s initialized with "data" and insert it into coll again:
std::string s = "data";
coll.push_back(s);
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 12
So far, there is nothing to optimize and we get the same state as with C++03:
We have two vectors, v and coll, and two strings, s and its copy, which is the first element in coll.
They should all be separate objects with their own memory for the value, because modifying one of them
should not impact any of the other objects.
• This is where things change. First, let us look at the statement that creates a new temporary string and
inserts it into the vector:
coll.push_back(s+s);
Again, this statement is performed in three steps:
1. We create the temporary string s+s:
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 13
2. We insert this temporary string into the vector coll. However, here something different happens now:
we steal the memory for the value from s+s and move it to the new element of coll.
This is possible because since C++11, we can implement special behavior for getting a value that is
no longer needed. The compiler can signal this fact because it knows that right after performing the
push_back() call, the temporary object s+s will be destroyed. So, we call a different implementation
of push_back() provided for the case when the caller no longer needs that value. As we can see, the
effect is an optimized implementation of copying a string where we no longer need the value: instead
of creating an individual deep copy, we copy both the size and the pointer to the memory. However,
that shallow copy is not enough; we also modify the temporary object s+s by setting the size to 0 and
assigning the nullptr as new value. Essentially, s+s is modified so that it gets the state of an empty
string. The important point is that it no longer owns its memory. And that is important because we
still have a third step in this statement.
3. At the end of the statement, the temporary string s+s is destroyed because we no longer need it.
However, because the temporary string is no longer the owner of the initial memory, the destructor
will not free this memory.
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 14
Essentially, we optimize the copying so that we move the ownership of the memory for the value of s+s
to its copy in the vector.
This is all done automatically by using a compiler that can signal that an object is about to die, so that
we can use new implementations to copy a string value that steals the value from the source. It is not a
technical move; it is a semantic move implemented by technically moving the memory for the value from
the source string to its copy.
• The next statement is the statement we modified for the C++11 version. Again, we insert s into coll,
but the statement has changed by calling std::move() for the string s that we insert:
coll.push_back(std::move(s));
Without std::move(), the same would happen as with the first call of push_back(): the vector would
create a deep copy of the passed string s. However, in this call, we have marked s with std::move(),
which semantically means “I no longer need this value here.” As a consequence, we have another call of
the other implementation of push_back(), which was used when we passed the temporary object s+s.
The third element steals the value by moving the ownership of the memory for the value from s to its
copy:
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 15
Note the following two very important things to understand about move semantics:
– std::move(s) only marks s to be movable in this context. It does not move anything. It only says,
“I no longer need this value here.” It allows the implementation of the call to benefit from this mark
by performing some optimization when copying the value, such as stealing the memory. Whether the
value is moved is something the caller does not know.
– However, an optimization that steals the value has to ensure that the source object is still in a valid state.
A moved-from object is neither partially nor fully destroyed. The C++ standard library formulates this
for its types as follows: after an operation called for an object marked with std::move(), the object
is in a valid but unspecified state.
That is, after calling
coll.push_back(std::move(s));
it is guaranteed that s is still a valid string. You can do whatever you want as long as it is valid for
any string where you do not know the value. It is like using a string parameter where you do not know
which value was passed.
Note that it is also not guaranteed that the string either has its old value or is empty. The value it
has is up to the implementers of the (library) function. In general, implementers can do with objects
marked with std::move() whatever they like, provided they leave the object in a valid state. There
are good reasons for this guarantee, which will be discussed later.
is about to die. That is, if the named return value optimization is not used, move semantics will be used,
which means that the return value steals the value from coll. At worst, we have to copy the members
for size, capacity, and the pointer to the memory (in total, usually 12 or 24 bytes) from the source to the
return value and assign new values to these members in the source.
Let us assume that we have the named return value optimization. In that case, at the end of the return
statement, coll now becomes the return value and the destructor of s is called, which no longer has to
free any memory because it was moved to the third element of coll:
Again, the temporary object is not (partially) destroyed. It enters into a valid state but we do not know its
value.
However, right after the assignment, the end of the statement destroys the (modified) temporary return
value:
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 18
At the end we are in the same state as before using move semantics but something significant has changed:
we saved six allocations and releases of memory. All unnecessary memory allocations no longer took place:
• Allocations for inserting a temporary object into the collection
• Allocations for inserting a named object into the collection, when we use std::move() to signal that we
no longer need the value
• Allocations for assigning a temporary vector with all its elements
In the second case, the optimization was done with our help. By adding std::move(), we had to say that
we no longer needed the value of s there. All other optimizations happened because the compiler knows that
an object is about to die, meaning that it can call the optimized implementation, which uses move semantics.
This means that returning a vector of strings and assigning it to an existing vector is no longer a perfor-
mance issue. We can use a vector of strings naively like an integral type and get much better performance.
In practice, recompiling code with move semantics can improve speed by 10% to 40% (depending on how
naive the existing code was).
The second push_back() uses a new syntax introduced for move semantics. We declare the argument with
two & and without const. Such an argument is called an rvalue reference.3 “Ordinary references” that
have only one & are now called lvalue references. That is, in both calls we pass the value to be inserted by
reference. However, the difference is as follows:
• With push_back(const T&), we promise not to modify the passed value.
This function is called when the caller still needs the passed value.
• With push_back(T&&), the implementation can modify the passed argument (therefore it is not const)
to “steal” the value. The semantic meaning is still that the new element receives the value of the passed
argument but we can use an optimized implementation that moves the value into the vector.
This function is called when the caller no longer needs the passed value. The implementation has to
ensure that the passed argument is still in a valid state. However, the value may be changed. Therefore,
after calling this, the caller can still use the passed argument as long as the caller does not make any
assumption about its value.
However, a vector does not know how to copy or move an element. After making sure that the vector has
enough memory for the new element, the vector delegates the work to the type of the elements.
In this case, the elements are strings. So, let us see what happens if we copy or move the passed string.
public:
// copy constructor: create a full copy of s:
string (const string& s)
: len{s.len} { // copy number of characters
if (len > 0) { // if not empty
data = new char[len+1]; // - allocate new memory
memcpy(data, s.data, len+1); // - and copy the characters
}
}
...
};
Given that we call this copy constructor for a string that has the value "data":
3 The reason this is called an rvalue reference is discussed later in the chapter about value categories.
4 The implementation of class std::string is more complicated because for its internal memory management it uses
optimizations and allocators (helper objects that define the way to allocate memory).
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 20
std::string a = "data";
std::string b = a; // create b as a copy of a
after initializing the string a as follows:
the copy constructor above would copy the member len for the number of characters but assign new memory
for the value to the data pointer and copy all characters from the source a (passed as s) to the new string:
public:
...
// move constructor: initialize the new string from s (stealing the value):
string (string&& s)
: len{s.len}, data{s.data} { // copy number of characters and pointer to memory
s.data = nullptr; // release the memory for the source value
s.len = 0; // and adjust number of characters accordingly
}
...
};
Given the situation from the copy constructor above:
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 21
However, this is not enough, because the destructor of b would free the memory. Therefore, we also modify
the source string to lose its ownership of the memory and bring it into a consistent state representing the
empty string:
The effect is that c now has the former value of b and that b is the empty string. Again, note that the
only guarantee is that b is subsequently in a valid but unspecified state. Depending on the way the move
constructor is implemented in a C++ library, it might not be empty (but it usually is because this is the easiest
and best way to improve performance here).
class MyVector {
public:
...
void push_back (const T& elem); // insert a copy of elem
... // no other push_back() declared
};
We can still pass a temporary object or an object marked with std::move():
MyVector<std::string> coll;
std::string s{"data"};
...
coll.push_back(std::move(s)); // OK, uses copy semantics
The rule is that for a temporary object or an object marked with std::move(), if available, a function
declaring the parameter as an rvalue reference is preferred. However, if no such function exists, the usual
copy semantics is used. That way, we ensure that the caller does not have to know whether an optimization
exists. The optimization might not exist because:
• The function/class was implemented before move semantics was supported or without having move se-
mantics support in mind
• There is nothing to optimize (a class with only numeric members would be an example of that)
For generic code, it is important that we can always mark an object with std::move() if we no longer need
its value. The corresponding code compiles even if there is no move semantics support.
For the same reason, you can even mark objects of a fundamental data type such as int (or a pointer)
with std::move(). The usual value semantics copying the value (the address) will still be used:
std::vector<int> coll;
int x{42};
...
coll.push_back(std::move(x)); // OK, but copies x (std::move() has no effect)
1.5 Summary 23
};
the only valid function to call for const objects is the first overload of push_back() with the const&
parameter:
std::vector<std::string> coll;
const std::string s{"data"};
...
coll.push_back(std::move(s)); // OK, calls push_back(const std::string&)
That means that a std::move() for const objects essentially has no effect.
In principle, we could provide a special overload for this case by declaring a function taking a const
rvalue reference. However, this makes no semantic sense. Again, the const lvalue reference overload
serves as a fallback to handle this case.
std::vector<std::string> coll;
...
coll.push_back(getValue()); // copies (because the return value is const)
When returning by value, do not declare the return value as a whole to be const. Use const only to declare
parts of your return type (such as the object a returned reference or pointer refers to):
const std::string getValue(); // BAD: disables move semantics for return values
const std::string& getRef(); // OK
const std::string* getPtr(); // OK
1.5 Summary
• Move semantics allows us to optimize the copying of objects, where we no longer need the value. It can be
used implicitly (for unnamed temporary objects or local return values) or explicitly (with std::move()).
• std::move() means I no longer need this value here. It marks the object as movable. An object marked
with std::move() is not (partially) destroyed (the destructor still will be called).
• By declaring a function with a non-const rvalue reference (such as std::string&&), you define an
interface where the caller semantically claims that it no longer needs the passed value. The implementer
of the function can use this information to optimize its task by “stealing” the value or do any other
modification with the passed argument. Usually, the implementer also has to ensure that the passed
argument is in a valid state after the call.
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 24
• Moved-from objects of the C++ standard library are still valid objects, but you no longer know their
value.
• Copy semantics is used as a fallback for move semantics (if copy semantics is supported). If there is no
implementation taking an rvalue reference, any implementation taking an ordinary const lvalue reference
(such as const std::string&) is used. This fallback is then used even if the object is explicitly marked
with std::move().
• Calling std::move() for a const object usually has no effect.
• If you return by value (not by reference), do not declare the return value as a whole to be const.
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 25
Chapter 2
Core Features of Move Semantics
After the first motivating example, this chapter discusses the basic features of move semantics.
25
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 26
std::string s{"hello"};
...
std::string&& r1 = std::move(s); // OK, rvalue reference to s
std::string&& r2{std::move(s)}; // OK, rvalue reference to s
std::string&& r3(std::move(s)); // OK, rvalue reference to s
All these references have the semantics of “we can steal/modify the object we refer to, provided the state
of the object remains a valid state.” Technically, these semantics are not checked by compilers, so we can
modify an rvalue reference as we can do with any non-const object of the type. We might also decide not
to modify the value. That is, if you have an rvalue reference to an object, the object might receive a different
value (which might or might not be the value of a default-constructed object) or it might keep its value.
As we have seen, move semantics allows us to optimize using a value of a source that no longer needs the
value. If compilers automatically detect that a value is used from an object that is at the end of its lifetime,
they will automatically switch to move semantics. This is the case when:
• We pass the value of a temporary object that will automatically be destroyed after the statement.
• We pass a non-const object marked with std::move().
2.2 std::move() 27
std::cout << s << '\n'; // OOPS, you don’t know which value is printed
foo(std::move(s)); // OOPS, you don’t know which value is passed
s = "hello again"; // OK, but rarely done
foo(std::move(s)); // OK, value of s might change
For both lines marked with “OOPS,” the call is technically OK as long as you make no assumption about
the current value of s. Printing out the value is therefore fine, although usually not very useful.
2.2 std::move()
If you have an object for which the lifetime does not end when you use it, you can mark it with std::move()
to express “I no longer need this value here.” std::move() does not move; it only sets a temporary marker
in the context where the expression is used:
void foo1(const std::string& lr); // binds to the passed object without modifying it
void foo1(std::string&& rv); // binds to the passed object and might steal/modify the value
...
std::string s{"hello"};
...
foo1(s); // calls the first foo1(), s keeps its value
foo1(std::move(s)); // calls the second foo1(), s might lose its value
Objects marked with std::move() can still be passed to a function that takes an ordinary const lvalue
reference:
void foo2(const std::string& lr); // binds to the passed object without modifying it
... // no other overload of foo2()
std::string s{"hello"};
...
foo2(s); // calls foo2(), s keeps its value
foo2(std::move(s)); // also calls foo2(), s keeps its value
Note that an object marked with std::move() cannot be passed to a non-const lvalue reference:
void foo3(std::string&); // modifies the passed argument
...
std::string s{"hello"};
...
foo3(s); // OK, calls foo3()
foo3(std::move(s)); // ERROR: no matching foo3() declared
Note that it does not make sense to mark a dying object with std::move(). In fact, this can even be
counterproductive for optimizations.
Programs using std::move() usually compile without including this header file, because in practice almost
all header files include <utility>. However, no standard header file is required to include utility.
Therefore, when using std::move(), you should explicitly include <utility> to make your program
portable.
Although you do not know the value, the string is in a consistent state. For example, s.size() will return
the number of characters so that you can iterate over all valid indexes:
foo(std::move(s)); // keeps s in a valid but unclear state
1 The guarantees for moved-from library objects were clarified with the library working group issue 2839 (see http:
//wg21.link/lwg2839).
Josuttis: C++ Move Semantics 2022/04/19 13:28 page 31
The semantic meaning is that we give foo() write access to the passed argument to steal the value. It is
an in parameter with the additional constraint that the caller no longer needs the value.
Note that rvalue references bind to other arguments than non-const lvalue references. Therefore, we had
to introduce a new syntax and could not just implement move semantics as a different way of functions that
modify passed arguments.
2.6 Summary
• Rvalue references are declared with && and no const.
• They can be initialized by temporary objects that do not have a name or non-const objects marked with
std::move().
• Rvalue references extend the lifetime of objects returned by value.
• std::move() is a static_cast to the corresponding rvalue reference type. This allows us to pass a
named object to an rvalue reference.
• Objects marked with std::move() can also be passed to functions taking the argument by const lvalue
reference but not taking a non-const lvalue reference.
Random documents with unrelated
content Scribd suggests to you:
mysterious, and holy, but also rich. For it was to the contented ease
of his early days that he was looking for release; the little haven in
Bedford Park had not come into his dreams. Indeed, I don’t suppose
he had even heard of Bedford Park at that time. It was Islington or
The Manor House; anything in between was Islington. But, of
course, he never confessed to himself that she would need to be
rich.
And he found her. He came over the hills on a gentle April morning
and saw her beneath him. She was caught, it seemed, in a hedge.
How gallantly George bore down to the rescue!
“Can I be of any assistance?” he said in his best manner, and that, I
think, is always the pleasantest way to begin. Between “Can I be of
any assistance?” and “With all my worldly goods I thee endow” one
has not far to travel.
“I’m caught,” she said. “If you could——” Observe George spiking
himself fearlessly.
“I say, you really are! Wait a moment.”
“It’s very kind of you.”
There—he has done it.
“Thank you so much,” she said, with a pretty smile. “Oh, you’ve hurt
yourself!”
The sweet look of pain on her face!
“It’s nothing,” said George nobly. And it really was nothing. One can
get a delightful amount of blood and sympathy from the most
insignificant scratch.
They hesitated a moment. She looked on the ground; he looked at
her. Then his eyes wandered round the beautiful day, and came back
to her just as she looked up.
“It is a wonderful day, isn’t it?” he said suddenly.
“Yes,” she breathed.
It seemed absurd to separate on such a day when they were both
wandering, and Heaven had brought them together.
“I say, dash it,” said George suddenly: “what are you going to do?
Are you going anywhere particular?”
“Not very particular.”
“Neither am I. Can’t we go there together?”
“I was just going to have lunch.”
“So was I. Well, there you are. It would be silly if you sat here and
ate—what are yours, by the way?”
“Only mutton, I’m afraid.”
“Ah, mine are beef. Well, if you sat here and ate mutton sandwiches
and I sat a hundred yards farther on and ate beef ones, we should
look ridiculous, shouldn’t we?”
“It would be rather silly,” she smiled.
So they sat down and had their sandwiches together.
“My name is Carfax,” he said, “Geoffrey Carfax.” Oh, George! And to
a woman! However, she wouldn’t tell him hers.
They spent an hour over lunch. They wandered together for another
hour. Need I tell you all the things they said? But they didn’t talk of
London.
“Oh, I must be going,” she said suddenly. “I didn’t know it was so
late. No, I know my way. Don’t come with me. Good-bye.”
“It can’t be good-bye,” said George in dismay. “I’ve only just found
you. Where do you live? Who are you?”
“Don’t let’s spoil it,” she smiled. “It’s been a wonderful day—a
wonderful little piece of a day. We’ll always remember it. I don’t
think it’s meant to go on; it stops just here.”
“I must see you again,” said George firmly. “Will you be there to-
morrow, at the same time—at the place where we met?”
“I might.” She sighed. “And I mightn’t.”
But George knew she would.
“Then good-bye,” he said, holding out his hand.
“My name is Rosamund,” she whispered, and fled.
He watched her out of sight, marvelling how bravely she walked.
Then he started for home, his head full of strange fancies....
He found a road an hour later; the road went on and on, it turned
and branched and doubled—he scarcely noticed it. The church clock
was striking seven as he came into the village.
It was a wonderful lunch he took with him next day. Chicken and
tongue and cake and chocolate and hard-boiled eggs. He ate it alone
(by the corner of a wood, five miles from the hedge which captured
her) at half-past three. That day was a nightmare. He never found
the place again, though he tried all through the week remaining to
him. He had no hopes after that day of seeing her, but only to have
found the hedge would have been some satisfaction. At least he
could sit there and sigh—and curse himself for a fool.
He went back to Islington knowing that he had had his chance and
missed it. By next April he had forgotten her. He was convinced that
she was not the woman. The woman had still to be found. He went
to another part of the country and looked for her.
And now he was back at “The Dog and Duck” again. Surely he would
find her to-day. It was the time; it must be almost the place. Would
the loved one be there? He was not sure whether he wanted her to
be the woman of five years ago or not. Whoever she was, she would
be the one he sought. He had walked some miles; funny if he
stumbled upon the very place suddenly.
Memories of five years ago were flooding his mind. Had he really
been here, or had he only dreamed of it? Surely that was the hill
down which he had come; surely that clump of trees on the right
had been there before. And—could that be the very hedge?
It was.
And there was a woman caught in it.
IV
George ran down the hill, his heart thumping heavily at his ribs....
She had her back towards him.
“Can I be of any assistance?” he said in his best manner. But she
didn’t need to be rich now; there was that little house at Bedford
Park.
She turned round.
It was Gertie Morrison!
Silly of him; of course, it wasn’t Miss Morrison; but it was
extraordinarily like her. Prettier, though.
“Why, Mr. Crosby!” she said.
It was Gertie Morrison.
“You!” he said angrily.
He was furious that such a trick should have been played upon him
at this moment; furious to be reminded suddenly that he was
George Crosby of Muswell Hill. Muswell Hill, the boarding-house—
Good Lord! Gertie Morrison! Algy Traill’s Gertie.
“Yes, it’s me,” she said, shrinking from him. She saw he was angry
with her; she vaguely understood why.
Then George laughed. After all, she hadn’t deliberately put herself in
his way. She could hardly be expected to avoid the whole of England
(outside Muswell Hill) until she knew exactly where George Crosby
proposed to take his walk. What a child he was to be angry with her.
When he laughed, she laughed too—a little nervously.
“Let me help,” he said. He scratched his fingers fearlessly on her
behalf. What should he do afterwards? he wondered. His day was
spoilt anyhow. He could hardly leave her.
“Oh, you’ve hurt yourself!” she said. She said it very sweetly, in a
voice that only faintly reminded him of the Gertie of Muswell Hill.
“It’s nothing,” he answered, as he had answered five years ago.
They stood looking at each other. George was puzzled.
“You are Miss Morrison, aren’t you?” he said. “Somehow you seem
different.”
“You’re different from the Mr. Crosby I know.”
“Am I? How?”
“It’s dreadful to see you at the boarding-house.” She looked at him
timidly. “You don’t mind my mentioning the boarding-house, do
you?”
“Mind? Why should I?” (After all, he still had another week.)
“Well, you want to forget about it when you’re on your holiday.”
Fancy her knowing that.
“And are you on your holiday too?”
She gave a long deep sigh of content.
“Yes,” she said.
He looked at her with more interest. There was colour in her face;
her eyes were bright; in her tweed skirt she looked more of a
country girl than he would have expected.
“Let’s sit down,” he said. “I thought you always went to Mar—to
Cliftonville for your holiday?”
“I always go to my aunt’s there in the summer. It isn’t really a
holiday; it’s more to help her; she has a boarding-house too. And it
really is Cliftonville—only, of course, it’s silly of mother to mind
having it called Margate. Cliftonville’s much worse than Margate
really. I hate it.”
(This can’t be Gertie Morrison, thought George. It’s a dream.)
“When did you come here?”
“I’ve been here about ten days. A girl friend of mine lives near here.
She asked me suddenly just after you’d gone—I mean about a
fortnight ago. Mother thought I wasn’t looking well and ought to go.
I’ve been before once or twice. I love it.”
“And do you have to wander about the country by yourself? I mean,
doesn’t your friend—I say, I’m asking you an awful lot of questions.
I’m sorry.”
“That’s all right. But, of course, I love to go about alone, particularly
at this time of year. You understand that.”
Of course he understood it. That was not the amazing thing. The
amazing thing was that she understood it.
He took his sandwiches from his pocket.
“Let’s have lunch,” he said. “I’m afraid mine are only beef.”
“Mine are worse,” she smiled. “They’re only mutton.”
A sudden longing to tell her of his great adventure of five years ago
came to George. (If you had suggested it to him in March!)
“It’s rather funny,” he said, as he untied his sandwiches—“I was
down here five years ago——”
“I know,” she said quietly.
George sat up suddenly and stared at her.
“It was you!” he cried.
“Yes.”
“You. Good Lord!... But your name—you said your name was—wait a
moment—that’s it! Rosamund!”
“It is. Gertrude Rosamund. I call myself Rosamund in the country. I
like to pretend I’m not the”—she twisted a piece of grass in her
hands, and looked away from him over the hill—“the horrible girl of
the boarding-house.”
George got on to his knees and leant excitedly over her.
“Tell me, do you hate and loathe and detest Traill and the Fossetts
and Ransom as much as I do?”
She hesitated.
“Mr. Ransom has a mother in Folkestone he’s very good to. He’s not
really bad, you know.”
“Sorry. Wash out Ransom. Traill and the Fossetts?”
“Yes. Oh yes. Oh yes, yes, yes.” Her cheeks flamed as she cried it,
and she clenched her hands.
George was on his knees already, and he had no hat to take off, but
he was very humble.
“Will you forgive me?” he said. “I think I’ve misjudged you. I mean,”
he stammered—“I mean, I don’t mean—of course, it’s none of my
business to judge you—I’m speaking like a prig, I—oh, you know
what I mean. I’ve been a brute to you. Will you forgive me?”
She held out her hand, and he shook it. This had struck him, when
he had seen it on the stage, as an absurdly dramatic way of making
friends, but it seemed quite natural now.
“Let’s have lunch,” she said.
They began to eat in great content.
“Same old sandwiches,” smiled George. “I say, I suppose I needn’t
explain why I called myself Geoffrey Carfax.” He blushed a little as
he said the name. “I mean, you seem to understand.”
She nodded. “You wanted to get away from George Crosby; I know.”
And then he had a sudden horrible recollection.
“I say, you must have thought me a beast. I brought a terrific lunch
out with me the next day, and then I went and lost the place. Did
you wait for me?”
Gertie would have pretended she hadn’t turned up herself, but
Rosamund said, “Yes, I waited for you. I thought perhaps you had
lost the place.”
“I say,” said George, “what lots I’ve got to say to you. When did you
recognise me again? Fancy my not knowing you.”
“It was three years, and you’d shaved your moustache.”
“So I had. But I could recognise people just as easily without it.”
She laughed happily. It was the first joke she had heard him make
since that day five years ago.
“Besides, we’re both different in the country. I knew you as soon as
I heard your voice just now. Never at all at Muswell Hill.”
“By Jove!” said George, “just fancy.” He grinned at her happily.
After lunch they wandered. It was a golden afternoon, the very
afternoon they had had five years ago. Once when she was crossing
a little stream in front of him, and her foot slipped on a stone, he
called out, “Take care, Rosamund,” and thrilled at the words. She let
them pass unnoticed; but later on, when they crossed the stream
again lower down, he took her hand and she said, “Thank you,
Geoffrey.”
They came to an inn for tea. How pretty she looked pouring out the
tea for him—not for him, for them; the two of them. She and he! His
thoughts became absurd....
Towards the end of the meal something happened. She didn’t know
what it was, but it was this. He wanted more jam; she said he’d had
enough. Well, then, he wasn’t to have much, and she would help
him herself.
He was delighted with her.
She helped him ... and something in that action brought back swiftly
and horribly the Gertie Morrison of Muswell Hill, the Gertie who sat
next to Algy and helped him to cabbage. He finished his meal in
silence.
She was miserable, not knowing what had happened.
He paid the bill and they went outside. In the open air she was
Rosamund again, but Rosamund with a difference. He couldn’t bear
things like this. As soon as they were well away from the inn he
stopped. They leant against a gate and looked down into the valley
at the golden sun.
“Tell me,” he said, “I want to know everything. Why are you—what
you are, in London?”
And she told him. Her mother had not always kept a boarding-
house. While her father was alive they were fairly well off; she lived
a happy life in the country as a young girl. Then they came to
London. She hated it, but it was necessary for her father’s business.
Then her father died, and left nothing.
“So did my father,” said George under his breath.
She touched his hand in sympathy.
“I was afraid that was it.... Well, mother tried keeping a boarding-
house. She couldn’t do it by herself. I had to help. That was just
before I met you here.... Oh, if you could know how I hated it. The
horrible people. It started with two boarders. Then there was one—
because I smacked the other one’s face. Mother said that wouldn’t
do. Well, of course, it wouldn’t. I tried taking no notice of them.
Well, that wouldn’t do either. I had to put up with it; that was my
life.... I used to pretend I was on the stage and playing the part of a
landlady’s vulgar daughter. You know what I mean; you often see it
on the stage. That made it easier—it was really rather fun
sometimes. I suppose I overplayed the part—made it more common
than it need have been—it’s easy to do that. By-and-by it began to
come natural; perhaps I am like that really. We weren’t anybody
particular even when father was alive. Then you came—I saw you
were different from the rest. I knew you despised me—quite right
too. But you really seemed to hate me, I never quite knew why. I
hadn’t done you any harm. It made me hate you too.... It made me
want to be specially vulgar and common when you were there, just
to show you I didn’t mind what you thought about me.... You were
so superior.
“I got away in the country sometimes. I just loved that. I think I was
really living for it all the time.... I always called myself Rosamund in
the country.... I hate men—why are they such beasts to us always?”
“They are beasts,” said George, giving his sex away cheerfully. But
he was not thinking of Traill and the Fossetts; he was thinking of
himself. “It’s very strange,” he went on; “all the time I thought that
the others were just what they seemed to be, and that I alone had a
private life of my own which I hid from everybody. And all the time
you.... Perhaps Traill is really somebody else sometimes. Even
Ransom has his secret—his mother.... What a horrible prig I’ve
been!”
“No, no! Oh, but you were!”
“And a coward. I never even tried.... I might have made things much
easier for you.”
“You’re not a coward.”
“Yes, I am. I’ve just funked life. It’s too much for me, I’ve said, and
I’ve crept into my shell and let it pass over my head.... And I’m still a
coward. I can’t face it by myself. Rosamund, will you marry me and
help me to be braver?”
“No, no, no,” she cried, and pushed him away and laid her head on
her arms and wept.
Saved, George, saved! Now’s your chance. You’ve been rash and
impetuous, but she has refused you, and you can withdraw like a
gentleman. Just say “I beg your pardon,” and move to Finsbury Park
next month ... and go on dreaming about the woman. Not a
landlady’s vulgar little daughter, but——
George, George, what are you doing?
He has taken the girl in his arms! He is kissing her eyes and her
mouth and her wet cheeks! He is telling her....
I wash my hands of him.
V
John Lobey, landlord of “The Dog and Duck,” is on the track of a
mystery. Something to do with they anarchists and such-like. The
chief clue lies in the extraordinary fact that on three Sundays in
succession Parson has called “George Crosby, bachelor, of this
parish,” when everybody knows that there isn’t a Crosby in the
parish, and that the gentleman from London, who stayed at his inn
for three weeks and comes down Saturdays—for which purpose he
leaves his bag and keeps on his room—this gentleman from London,
I tell you, is Mr. Geoffrey Carfax. Leastways it was the name he
gave.
John Lobey need not puzzle his head over it. Geoffrey Carfax is
George Crosby, and he is to be married next Saturday at a
neighbouring village church, in which “Gertrude Rosamund Morrison,
spinster, of this parish,” has also been called three times. Mr. and
Mrs. Crosby will then go up to London and break the news to Mrs.
Morrison.
“Not until you are my wife,” said George firmly, “do you go into that
boarding-house again.” He was afraid to see her there.
“You dear,” said Rosamund; and she wrote to her mother that the
weather was so beautiful, and she was getting so much stronger,
and her friend so much wanted her to stay, that ... and so on. It is
easy to think of things like that when you are in love.
On the Sunday before the wedding George told her that he had
practically arranged about the little house in Bedford Park.
“And I’m getting on at the office rippingly. It’s really quite interesting
after all. I shall get another rise in no time.”
“You dear,” said Rosamund again. She pressed his hand tight and....
But really, you know, I think we might leave them now. They have
both much to learn; they have many quarrels to go through, many
bitter misunderstandings to break down; but they are alive at last.
And so we may say good-bye.
The Cherub
By Oliver Onions
The July sun beat fiercely down on the grey walls, and the sentry’s
tunic was of a glaring bull’s red. Not a breath moved the trees
below, and the click of his heels sounded monotonously.
Within the shadow of the South Bar, where the steps wound down to
the street, a frock-coated, square-built man of forty, with clipped
whiskers and crafty eyes, watched the sentry approach. For the
second time he cleared his throat and said “Tom!”
This time the sentry turned. “I ain’t allowed to talk on duty,” he said.
The man within the shadow waited.
He waited for half an hour, and then the clatter of the relief was
heard ascending the turret. Presently Private Hey passed him
without looking at him. He descended after him, and in the street
spoke again.
“I ain’t off duty yet; you can come to the Buttercup,” said Private
Hey.
The bar of the Buttercup was below the level of the street, and a
gas-jet burned all day over its zinc-covered counter. In the back
parlour behind it Hullah awaited Private Hey.
The cherub’s voice was heard shouting an order, and he entered the
snug. The uncoated barman followed him with the liquor, and
retired.
“Did you want to speak to me?” the cherub demanded.
“I did, Tom, I did. How—how are you getting on?”
“Spit it out.”
Hullah murmured smoothly: “Ah, the same blunt-spoken, honest
Tom that was at Peterson’s! You remember Peterson’s and the old
days, Tom?”
“I’d let the old days drop if I was you. I thought you had done.”
“So did I, Tom, so did I; but every breast has its troubles. You’ve
heard the expression, Tom, that there is no cupboard without its
skeleton?”
“Keep your cupboards and skeletons to yourself.... Does the new
bathroom answer all right?”
“Nicely, Tom, I thank you.... Did you know Peterson was back in
Maychester?”
“Ho, is he? I expect he wants to talk over the old days with his
friend Hullah, same as you with me. Well, you was a precious pair o’
rascals—though for myself, mark you, I like to see honour among
such.”
“Hush, Tom!... He’s back, and seeking you. He’d better be careful;
it’s twenty years, is that. But what I wanted to say, Tom, is that it
would save a lot of trouble—a lot of trouble—if you weren’t to see
him.”
“Ho!... Hullah, my man.”
“Yes, Tom.”
“Do you know what I think you are?”
Hullah stammered. It was so hard to get a start in business—the
competition—he’d gone straight except for that once.
“I think you’re the blackguardest, off-est scamp in the trade, and I
wouldn’t be found dead in a ditch with you. That’s juicy, coming
from me. I’m no saint, but just a common-or-garden Tommy, with a
defaulter sheet it’s a sin to read; and I say you’re a blackguard, and
dead-off.”
Hullah cringed. He’d gone straight since—Peterson had already
pushed him for twice what he’d had out of it—it was hard to be
persecuted like this, hard. The cherub revolved in his mind phrases
of elaborate and over-done irony.
Suddenly Hullah mentioned his wife, and the pink of the cherub’s
face deepened.
“Come into the yard,” he said.
Hullah followed him into a dusty plot, where hens scratched and
cases and barrels lay scattered everywhere.
“What did you say?” the soldier demanded.
The architect’s face was of an unwholesome white, and Hey spat. He
saw that Hullah feared he was going to strike him.
“She’s been ill, Tom, and must be got away to the Mediterranean.
Peterson’s sucking me dry; he thinks I’m afraid of him. You used to
be fond of her, Tom.”
All at once Private Hey’s wrath gave place to utter wretchedness,
and he began to stride up and down the yard. Tears rose into his
eyes, and presently rolled unchecked down his cheeks. He
approached Hullah, and said in a quavering voice: “A fortnight ago—
was that?”
“A boy,” Hullah murmured.
“It’s a mercy he’s dead, if he’d ha’ been like you,” the cherub
sobbed.
And then he forgot all about Hullah. He forgot everything except that
little Mollie Westwood had been through an agony, was ill, must be
got away, and that he might help her. An ineffable, soft thrill stirred
at his heart; he, wicked Tom Hey, might help her. And presently he
stood before Hullah again, looking wistfully at him.
“You ain’t lying, Hullah?”
“Oh, Tom!”
“And suppose—suppose I was to think Peterson’s as big a thief as
you, and treat him as such—treat him as such, if he dares to speak
to me; you understand, Hullah?”
“Don’t put it that way, Tom ... then I may take it, Tom——?”
“Oh, go, go! I want to me by myself!” the poor cherub moaned; and
Hullah, turning once to dart a hateful glance at him over his
shoulder, passed through the public-house.
“It’s Siberia for you this time, Tom,” the guard whispered, adjusting
his pipe-clayed belt; “what in thunder made you go and do it?”
The cherub’s tunic was unbelted, and the colour had fled from his
simple face. He made no reply.
“Was you drunk? Barker says you hadn’t been in the canteen.
Anyway, the chap’s in ’orspital. A blooming civilian, too!”
He saluted stiffly; the major had passed on his way to the
outbuilding that had been furnished for a court-martial; and the
barrack clock struck eleven.
Half a dozen officers in full uniform sat about a long trestle-table,
and the sunlight that came through the tall windows lay across the
pens and ink and pink blotting-paper that were spread before the
Court. The colonel, at the head of the table, talked to Warren, the
regimental surgeon.
“I’m absurdly upset, Warren. It’s ridiculous, the faith I have in the
fellow. Moreover, I have reason to know that he hasn’t touched drink
for weeks.”
“He’s been in the habit, and in such cases a sudden discontinuance
sometimes.... But the point isn’t whether he was drunk or not; it’s an
unprovoked attack on this fellow Peterson, or whatever his name is.”
The colonel sighed. “Ah, well, I can’t overlook this. Are you ready,
gentlemen?”
An orderly opened the door, and the prisoner was brought in
between two armed guards. He saluted the Court, and then stood at
attention. The guards fell back. Two or three witnesses sat on a
bench within the door.
The colonel did not once look at Private Hey, and the charge was
read. The principal witness lay in hospital, but sufficient evidence of
the fact of the assault would be produced, and the president desired
the prisoner to plead. The plea was scarcely audible, but it was
understood to be “Not guilty,” and the first witness was called.
The cherub knew not in what queer way it hurt him that his colonel
refused to look at him. He didn’t much care what happened, but he
would have liked the colonel to think well of him. A witness was
telling how the prisoner had reeled, spoken thickly, offered his
bayonet, and finally flung the man down the steps of the turret of
the South Bar. Would the witness consider the prisoner to have been
drunk? the Court asked, and the witness replied that he should. The
steps were old and worn; might not the man have slipped? the Court
suggested, and the witness reminded the Court that the prisoner
had staggered and offered his bayonet. Had the injured man spoken
to the prisoner? The witness thought not; he had seemed to be on
the point of speaking, but the prisoner had cut him short,
exclaiming: “I don’t want to talk to dead-off’s—like you!”
Asked if he had anything to say, the prisoner shook his head. “I
wasn’t drunk, sir,” he said.
Other witnesses were called; the case went drowsily forward, and
the major yawned. The colonel was whispering to the doctor again,
and then for the first time he looked at the prisoner.
“Do you know this Peterson?”
“I worked for him when I was a civilian, sir,” the prisoner answered.
“Have you any grudge against him?”
“I didn’t want to talk to him, sir.”
“But suppose he should speak to you again?”
A brief gleam of satisfaction crossed the cherub’s mild blue eyes. “I
frightened him too bad for that, sir,” he said; and then, as the
colonel’s grave eyes did not cease to regard him, there came a quick
little break in his voice.
“I wasn’t drunk, sir. I wouldn’t tell you a lie, sir, nor do nothing that’s
off—there’s marks against me a many, but not for things that’s off; I
ask you to believe I wasn’t drunk, sir——”
“Clear the Court,” said the colonel.
The guard, the prisoner, and the witnesses filed out and the door
closed, and the colonel leaned forward in his chair. He seemed
disproportionately moved.
“Gentlemen,” he said, “if the prisoner is to be seriously punished, I
ask you to remember it’s dismissal and imprisonment. Let me make
a suggestion. It was a very hot day—he’s been in India—possibly an
old sunstroke——”
“A bit discredited, that,” observed the doctor.
“He would be punished, of course, but more leniently. It’s all I can
put forward. It rests with the Court.”
He leaned back again, troubled. In the hum of consultation he heard
Warren’s slightly sarcastic laugh, and thought he heard the major
say: “Oh, let it go at that; Neville seems to want it.”
“Very well, sir,” said the major by and by; “we are agreed.”
And as the cherub, returning with the guard, received the milder
sentence, he looked humbly and gratefully at his colonel. He
recognised that there are things that a commanding officer cannot
overlook, but that a private gentleman, on occasion, may.
An Impossible Person
By W. B. Maxwell
Royal Fusiliers
Using the cant phrase, people often said that General Sir John
Beckford was a quite impossible person. A brave soldier, a true
gentleman, a splendid creature physically—just so, but rendering
himself absurd and futile by notions so old-fashioned that they had
been universally exploded before he was born. A man who
obstinately refused to move with the times, who in manner,
costume, and every idea belonged, and seemed proud to belong, to
the past.
Even his own relatives admitted the impossibility of him when, at the
age of sixty, he gave effect to the most old-fashioned of all
conceivable notions by marrying for love. If an elderly widower with
a little son of nine wants somebody to make a home and help to
rear the child, he should invite some middle-aged female cousin to
come to his assistance; but if he wants a charming, attractive girl to
renounce the joys and hopes of youth in order to soothe and
gladden his dull remnant of years—well, he oughtn’t to want it, and
really it is not quite nice when he does.
Lady Jane Armitage, an ancient aunt, put this thought into very plain
words and forced Sir John to listen to them. A mistake—not even a
fair bargain. What is Cynthia to get, on her side? A seat in a
carriage, a liberal dress allowance, perhaps a few more loose
sovereigns than she has been accustomed to carry in that silly little
gold purse of hers!
“The idea of money,” said Sir John gruffly, “has never entered
Cynthia’s head.”
“Perhaps not. But what else can you offer her? To hold your landing-
net while you do your stupid fishing; to perform the duties of a
nursery-governess for Jack; to enjoy the privilege of playing hostess
when you entertain half a dozen other generals and their frumpish
wives.”
Sir John echoed his aunt’s last adjective ironically.
“Yes,” said Lady Jane, “but I’m different. I know I’m a frump, and
your friends aren’t aware of their misfortune. No, John, I tell you
frankly, it isn’t a fair bargain.”
Sir John bit his grey moustache, ran a strong hand through his shock
of grey hair, contracted his heavy brows, and then laughed and
shrugged his shoulders.
“Inexplicable to you, eh, Aunt Jane? Well, let’s leave it at that. But
be kind to Cynthia all the same, won’t you? Save her from the other
frumps,” and, ceasing to laugh, he stared at Lady Jane almost
fiercely.
He was one of those men who consider it beneath their dignity to
betray tender emotion, and who perhaps look sternest and most
forbidding when they are feeling unusually soft and gentle. At any
rate, he would not explain to his aunt that he believed the marriage
to be an eminently fair bargain—an old-fashioned exchange—love
for love—as much love on the girl’s side as on his.
Lady Jane made no promise, but she proved very kind indeed to her
new niece; endeavouring to find innocent amusement for pretty
Cynthia, acting as her chaperon, watching over her, and growing
fonder and fonder of her. She said that the young Lady Beckford was
a model wife and a pattern stepmother. No one could have been
more devoted to or wiser in her training of Master Jack.
Now, after five years, the boy was ready to go to a public school,
and during these long summer days a holiday tutor had been giving
him final preparation, ultimate crammed knowledge, and topmost
polish of tone and manners. August had been spent at the
Beckfords’ country house in Devonshire, and the early weeks of
September at their flat in Victoria Street. Lady Jane approved of
everything that concerned these arrangements, except one thing.
She approved of the public school, of the engaging of a holiday
tutor, of all the care, devotion, and forethought with which the little
man was being launched from the home circle; but she did not
approve of the fact that Sir John had thrown the whole burden on
Cynthia’s slender shoulders, while he did his stupid salmon-fishing
four hundred miles away in Scotland.
Not quite fair to Cynthia—leaving her all alone with a schoolboy and
his tutor. Lady Jane, at considerable inconvenience, ran down to
Devonshire to cheer and enliven her. Came back to London and at
worse inconvenience stayed there, so as to be handy to act as
companion, chaperon, advisory ally, whenever Cynthia wanted her.
But Cynthia wanted her scarcely at all, and allowed poor Lady Jane
to perceive at last that uninvited companions are sometimes a
tedium rather than a solace.
It was the last night of the holidays. To-morrow Master Jack and his
tutor would disappear from Victoria Street.
Dinner had been ordered at an early hour, and Jack was scampering
through his meal with excited swiftness. One last treat had been
arranged for him. He was to be dispatched to a theatre presently in
charge of George, the footman.
“I wish you were coming,” said Jack, and as he turned to Mr.
Ridsdale his eyes expressed eloquently enough the hero-worship
that is so easy to kindle in young and ingenuous hearts.
“It would be scarcely polite,” said Mr. Ridsdale, “for both of us to
desert Lady Beckford.”
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.
ebookbell.com