Martin Sebor wrote:
Farid Zaripov wrote:
Whether these examples should be abstract, or based on C++ Standard
Library
declarations/definitions?
Examples using the C++ standard library classes or functions would
be great, but any other sort will, in my opinion, work just as well.
The point is to highlight the general kind of changes people might
easily think are compatible when in reality they're not.
Since the source incompatible changes involves changes in
function/class mebmers
prototype, or changes in global data/class data members declaration, or
changing the
place of the some declaration (i.e. moving the declaration from one
header file to the another),
but requirements of the all of this are stated in C++ Standard and,
accordingly, any of these
changes are impossible.
Let me give one example where this isn't true. The standard leaves
it up to each implementation to decide whether to define overloads
of certain functions or whether to make use of default function
arguments. For instance, vector::resize() can be declared in one
of two ways:
resize(size_type, value_type = value_type());
or
resize(size_type);
resize(size_type, value_type);
Changing from one form to the other is detectable and might qualify
as a breaking change. First, programs that explicitly instantiate
vector on a user-defined type that's not default constructible will
compile with the first declaration but not with the second (because
the definition of the first overload must default-construct the
element). Second, programs that take the address of such functions
will not compile. The standard leaves the exact type of library
member functions unspecified so it's up to us whether we want to
go a step beyond and provide a stronger guarantee or not.
Or adding overloads with different behavior to functions that are
a better match for calls in existing programs. For instance, if we
added an overload for the ostream inserter for wchar_t* that did
something different than print the value of the pointer it would
break programs that insert wchar_t pointers into narrow streams.
So code like this: std::cout << L"insert a pointer"; inserts the
address of the wide string today, but if we added the overload it
would write the string itself.
--Mark