AK: Change the moved-from String state to the empty short string

The previous moved-from state was the null string. This violates both
our invariant that String is never null, and also the C++ contract that
the moved-from state must be valid but unspecified. The empty short
string state is of course valid, so it satisfies both invariants. It
also allows us to remove any extra checks for the null state.

The reason this change is made is primarily because swap() requires
moved-from objects to be reassignable (C++ allows this). Because the
move assignment of String would not check the null state, it crashed
trying to increment the data reference count (nullptr signals a
non-short string). This meant that e.g. quick_sort'ing String would
crash immediately.
This commit is contained in:
kleines Filmröllchen 2022-12-11 14:32:56 +01:00 committed by Linus Groh
parent ca80353efe
commit f502e24bd7
Notes: sideshowbarker 2024-07-17 21:26:19 +09:00

View file

@ -177,6 +177,7 @@ String::String(String const& other)
String::String(String&& other)
: m_data(exchange(other.m_data, nullptr))
{
other.m_short_string.byte_count_and_short_string_flag = SHORT_STRING_FLAG;
}
String& String::operator=(String&& other)
@ -185,6 +186,7 @@ String& String::operator=(String&& other)
m_data->unref();
m_data = exchange(other.m_data, nullptr);
other.m_short_string.byte_count_and_short_string_flag = SHORT_STRING_FLAG;
return *this;
}
@ -200,7 +202,7 @@ String& String::operator=(String const& other)
String::~String()
{
if (!is_short_string() && m_data)
if (!is_short_string())
m_data->unref();
}