Предположим есть некий давно присутствующий на рынке программный продукт, с API, которое использует огромное число разработчиков.
Причем некоторые из разработчиков используют это API не описанным в документации способом или даже прямо там запрещенном (не в юридическом смысле) и никаких проблем от этого до сих пор не возникало, потому что, де-факто, оно работало нужным образом, хотя и не позволенным документацией.
В один прекрасный момент разработчики чего-то там у себя переписали и внезапно недокументированное поведение функции из API изменилось, что поломало совместимость и привело к ошибкам в работе и возмущениям.
И вот кто тут прав?
Ситуация невымышленная. Недавно эта история приключилась в Linux.
Подробности можно узнать из
этого обсуждения.
Вкратце произошло вот что.
Есть важнейшая системная библиотека glibc (ее разработчики работают в основном в RedHat), в которой содержится сишный рантайм. В ней есть функция memcpy, копирующая память и описанная в документации как:
MEMCPY(3) Linux Programmer's Manual MEMCPY(3)
NAME
memcpy — copy memory area
SYNOPSIS
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
DESCRIPTION
The memcpy() function copies n bytes from memory area src to memory
area dest. The memory areas should not overlap. Use memmove(3) if the
memory areas do overlap.
Она копирует из одной области памяти в другую заданное число байт. Специально указывается, что источник и приемник не должны пересекаться, если пересекаются необходимо использовать вместо memcpy функцию memmove. При том такое описание было с весьма древних пор, минимум с 1993-ого года или вообще с самого начала.
Но де-факто, реализация memcpy в glibc позволяла спокойно копировать и пересекающиеся области памяти. И вот разработчики чего-то там оптимизировали для увеличения скорости копирования, после чего в случае пересекающихся областей памяти копироваться они стали неверно.
Это привело к неправильному воспроизведению звука в плагине Adobe Flash player и к сбоям в некоторых других менее известных программах.
Разработчики glibc закрыли сообщение об ошибке по причине, что это не ошибка. Дискуссия развернулась довольно серьезная. В ней даже отметился лично Линус Торвальдс, который отнюдь не считает, что в glibc были правы, и даже ехидно спрашивает, собираются ли они выпустить дистрибутив Fedora 14 с заведомо неработоспособным флеш плеером?
В принципе, ошибка не в glibc, а в прикладных программах и для исправления достаточно банально заменить memcpy(...) на memmove(...) и заново откомпилировать программу. Для OpenSource — это особо не проблема, но в Linux-e работают и проприетарные программы, которые производители могут и не спешить исправлять. Правда Линус предложил способ решить проблему путем использования своей реализации memcpy и подкладывании своей библиотеки для конкретной программы. Но это костыль.
Такая вот любопытная дилемма получается. С одной стороны как бы разработчик не обязан обеспечивать совместимость за пределами документированного поведения, с другой стороны, вроде и поломка чужих важных программ после такого не есть хорошо.