Большие старые программные системы, развивающиеся десятилетиями, изобилуют разнообразнейшими атавизмами и просто участками кода, написанными с использованием популярных парадигм и стилей разнообразных лет. В таких системах можно наблюдать эволюцию развития языков программирования, когда наиболее старые части написаны в стиле языка Си, а в наиболее свежих можно встретить сложные шаблоны в стиле Александреску.
Есть атавизмы связанные и с 64-битностью. Вернее, атавизмы, препятствующие работе современного 64-битного кода. Приведу новый пример, о котором я недавно узнал.
Интересная ошибка относится к старой версии системы macOS X и содержится в функции malloc_zone_calloc:
// beyond this, assume a programming error
#define MAX_ALLOCATION 0xc0000000
// Allocate cleared (zero-filled) memory from
// the given zone for num_items objects,
// each of which is size bytes large
void *malloc_zone_calloc(malloc_zone_t *zone,
size_t num_items, size_t size)
{
void *ptr;
if (malloc_check_start &&
(malloc_check_counter++ >= malloc_check_start))
{
internal_check();
}
if (((unsigned)num_items >= MAX_ALLOCATION) ||
((unsigned)size >= MAX_ALLOCATION) ||
((long long)size * num_items >=
(long long) MAX_ALLOCATION))
{
/* Probably a programming error */
fprintf(stderr,
"*** malloc_zone_calloc[%d]: arguments too large: %d,%d\n",
getpid(), (unsigned)num_items, (unsigned)size);
return NULL;
}
ptr = zone->calloc(zone, num_items, size);
if (malloc_logger)
malloc_logger(MALLOC_LOG_TYPE_ALLOCATE |
MALLOC_LOG_TYPE_HAS_ZONE |
MALLOC_LOG_TYPE_CLEARED,
(unsigned)zone,
num_items * size, 0,
(unsigned)ptr, 0);
return ptr;
}
Во-первых, код функции содержит проверку на допустимые размеры выделяемой памяти, являющиеся странными для 64-битной системы. А во-вторых, выдаваемое диагностическое сообщение будет некорректно, поскольку если мы попросим выделить память под 4 400 000 000 элементов, из-за явного приведения типа к unsigned, нам будет выдано странное сообщение о невозможности выделения памяти всего лишь для 105 032 704 элементов.
Насколько я понял из заметки, эта странная проверка была убрана из функции только в 2006 году. Хотя возможно я ошибаюсь с датой исправления, но пример хорошо показывает, как легко забыть о чем-то старом.
0