переполнения в дополнениях size_t

Мне нравится, когда мой код предупрежден бесплатно для VS.NET и GCC, и мне нравится, когда мой код готов к 64-битной обработке.

Сегодня я написал небольшой модуль, который работает с буферами памяти и обеспечивает доступ к данным через интерфейс в стиле файла (например, вы можете читать байты, записывать байты, искать и т. Д.).

В качестве типа данных для текущей позиции чтения и typedef struct { unsigned char * m_Data ; size_t m_CurrentReadPosition ; size_t m_DataSize ; } MyMemoryFile ; Я использовал size_t, так как это, кажется, самый естественный выбор. Я получаю предупреждения, и они должны работать и в 64-битной среде.

На всякий случай: моя структура выглядит так:

size_t

Подпись, size_tкажется, не определена на практике. Поиск кода Google подтвердил это.

Теперь передо мной стоит дилемма: я хочу проверить дополнения на size_tналичие переполнений, потому что мне приходится иметь дело с предоставленными пользователем данными, а сторонние библиотеки будут использовать мой код. Тем не менее, для проверки переполнения я должен знать знак. Это имеет огромное значение в реализации.

Итак, как, черт возьми, мне писать такой код независимо от платформы и компилятора?

Могу ли я проверить подпись sizeво время выполнения или во время компиляции? Это решило бы мою проблему. Или, может быть, size_tне самая лучшая идея?

Есть идеи?

РЕДАКТИРОВАТЬ : Я ищу решение для языка Си!

c,integer-overflow,size-t,

8

Ответов: 6


12 принят

Относительно того, sizeявляется ли _t подписанным или неподписанным и GCC (из старого руководства GCC - я не уверен, что это все еще там):

Существует потенциальная проблема с size_tтипом и версиями GCC до выпуска 2.4. ANSI C требует, чтобы size_tвсегда был тип без знака. Для совместимости с существующими файлами заголовков систем, GCC определяет stddef.hв sys/types.hбыть любой тип системы size_tопределяет , что это будет. Большинство систем Unix, которые определяют sys/types.hв size_t, определяют его как тип со знаком. Некоторый код в библиотеке зависит от size_tтого, является ли он неподписанным типом, и не будет работать правильно, если он подписан.

Код библиотеки GNU C, который ожидает size_tбыть неподписанным, является правильным. Определение типа size_tсо знаком неверно. Мы планируем, что в версии 2.4 GCC всегда будет определяться sys/types.hкак тип без знака, а сценарий 'fixinclude' будет обрабатывать систему, size_tчтобы не конфликтовать с этим.

Тем временем, мы обходим эту проблему, явно говоря GCC использовать тип без знака для size_tкомпиляции библиотеки GNU C. 'configure' автоматически определит, какой тип GCC использует для size_tупорядочения, чтобы переопределить его при необходимости.

Если вы хотите , подписанную версию ptrdiff_tиспользования ssize_tили на некоторых системах есть ЬурейиЙ для size_t.


size_tявляется беззнаковым целочисленным типом, согласно стандартам C ++ C. Любая if (a + b < a)подписанная реализация серьезно несовместима и, вероятно, также имеет другие проблемы с переносимостью. Гарантируется, что при переполнении это оборачивается, что означает, что вы можете писать тесты, например, size_tчтобы найти переполнение.

size_tэто отличный тип для всего, что связано с памятью. Ты делаешь это правильно.


size_t должен быть без знака.

Обычно он определяется как unsigned long.

Я никогда не видел, чтобы это было определено иначе. ssize_tэто его подписанный аналог.

РЕДАКТИРОВАТЬ: GCC определяет его как подписанный в некоторых обстоятельствах. компиляция в режиме ASNI C или std-99 должна привести к тому, что он не будет подписан.


Для языка C используйте IntSafe . Также выпущен Microsoft (не путать с библиотекой C ++ SafeInt). IntSafe - это набор вызовов функций языка Си, которые могут выполнять математические операции и безопасно выполнять преобразования. обновлен URL для функций intsafe


Используйте safeint . Это класс, разработанный Майклом Ховардом и выпущенный как открытый исходный код от Microsoft. Он предназначен для работы с целыми числами, где переполнение определяется как риск. Все переполнения преобразуются в исключения и обрабатываются. Класс предназначен для облегчения правильного использования.

Например :

char CouldBlowUp(char a, char b, char c)
{
   SafeInt<char> sa(a), sb(b), sc(c);

   try
   {
     return (sa * sb + sc).Value();
   }
   catch(SafeIntException err)
   {
      ComplainLoudly(err.m_code);
   }

   return 0;
}

Кроме того, safeint часто используется в Microsoft в таких продуктах, как Office.

Ref: текст ссылки

с, целое число от переполнения, размер-т,
Похожие вопросы