Для начала позвольте мне сказать, что я понимаю, как и почему может возникнуть проблема, которую я описываю. Я был специалистом в области компьютерных наук, и я понимаю переполнение/недополнение и арифметику со знаком/без знака. (Для тех, кто не знаком с этой темой, руководство Apple по безопасному кодированию кратко обсуждает целочисленное переполнение.)
Мой вопрос касается сообщения и восстановления после такой ошибки после ее обнаружения, а точнее в случае с платформой Objective-C. (Я пишу и поддерживаю CHDataStructures.) У меня есть несколько классов коллекций, которые выделяют память для хранения объектов. и динамически расширяться по мере необходимости. Я еще не видел каких-либо сбоев, связанных с переполнением, вероятно, потому, что мои тестовые примеры в основном используют нормальные данные. Однако, учитывая непроверенные значения, все может взорваться довольно быстро, и я хочу предотвратить это.
Я определил как минимум два распространенных случая, когда это может произойти:
- Вызывающий передает очень большое значение без знака (или отрицательное значение со знаком) в
-initWithCapacity:
. - Было добавлено достаточно объектов, чтобы обеспечить динамическое расширение емкости, а емкость стала достаточно большой, чтобы вызвать переполнение.
Простая часть — определить, произойдет ли переполнение. (Например, прежде чем пытаться выделить length * sizeof(void*)
байт, я могу проверить, соответствует ли length <= UINT_MAX / sizeof(void*)
, поскольку провал этого теста будет означать, что продукт переполнится и потенциально выделит гораздо меньшую область памяти, чем хотелось бы. На платформах, которые это поддерживают, checkint.h API — еще одна альтернатива.) Более сложная часть определение того, как с этим справиться изящно. В первом сценарии звонящий, возможно, лучше подготовлен (или, по крайней мере, настроен) для того, чтобы справиться с ошибкой. Второй сценарий может произойти в любом месте кода, где объект добавляется в коллекцию, что может быть совершенно недетерминированным.
Тогда мой вопрос заключается в следующем: Как ожидается, что код Objective-C будет вести себя как «добропорядочный гражданин», когда в такой ситуации происходит целочисленное переполнение? (В идеале, поскольку мой проект представляет собой фреймворк в той же дух как Foundation в Cocoa, я хотел бы смоделировать его поведение для максимального «соответствия импеданса». Документация Apple, которую я нашел, вообще не упоминает об этом.) Я полагаю, что в любом случае, сообщение об ошибке является данностью. Поскольку API-интерфейсы для добавления объекта (что может вызвать сценарий 2) не принимают параметр ошибки, что я действительно могу сделать, чтобы помочь решить проблему, если что-нибудь? Что действительно считается нормальным в таких ситуациях? Я не хочу сознательно писать код, подверженный сбоям, если я могу сделать лучше...