﻿# Атавизмы в больших системах

Большие старые программные системы, развивающиеся десятилетиями, изобилуют разнообразнейшими атавизмами и просто участками кода, написанными с использованием популярных парадигм и стилей разнообразных лет\. В таких системах можно наблюдать эволюцию развития языков программирования, когда наиболее старые части написаны в стиле языка Си, а в наиболее свежих можно встретить сложные шаблоны в стиле Александреску\.

Есть атавизмы связанные и с 64\-битностью\. Вернее, атавизмы, препятствующие работе современного 64\-битного кода\. Приведу новый пример, о котором я недавно узнал\.

Интересная ошибка относится к старой версии системы macOS X и содержится в функции malloc\_zone\_calloc:

```cpp
// 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\-битной](https://pvs-studio.ru/ru/blog/terms/0001/) системы\. А во\-вторых, выдаваемое диагностическое сообщение будет некорректно, поскольку если мы попросим выделить память под 4 400 000 000 элементов, из\-за явного приведения типа к unsigned, нам будет выдано странное сообщение о невозможности выделения памяти всего лишь для 105 032 704 элементов\.

Насколько я понял из заметки, эта странная проверка была убрана из функции только в 2006 году\. Хотя возможно я ошибаюсь с датой исправления, но пример хорошо показывает, как легко забыть о чем\-то старом\.