Вопрос по c++ – size_t всегда без знака?

55

В качестве заголовка: size_t всегда без знака, то есть дляsize_t x, являетсяx всегда>= 0 ?

Некоторые цитаты из стандартного документа для всех утверждений ниже были бы хорошими. anon
Существует & quot; ssize_t & quot; для & quot; подписанного size_t & quot; :) Johannes Schaub - litb
Так не рекомендуется ли ptrdiff_t? finnw
спасибо, литб, но я счастлив, что это без подписи. Одна вещь меньше, чтобы проверить (в некоторых случаях) peterchen
Речь идет не о размере, а о том, как вы его используете :) ralphtheninja

Ваш Ответ

6   ответов
2

Size_t должен следовать тому же определению, что и стандарт C, и в нескольких местах в стандарте C ++ это подразумевает его неподписанную натуру (особенно в определениях аргументов шаблона распределителя).

О стандарте C ++, раздел 18.1 (ISO / IEC 14882 - первое издание 1998-01-01):

В таблице 15 перечислены определенные типы: ptrdiff_t и size_t

3 Содержимое совпадает с заголовком библиотеки Standard C со следующими изменениями: 4 Макрос NULL является константой нулевого указателя C ++, определенной реализацией, в этом международном стандарте (4.10).

Макрос offsetof принимает ограниченный набор аргументов типа в этом международном стандарте. тип должна быть структурой POD или объединением POD (пункт 9). Результат применения макроса offsetof к полю, является статическим членом данных или членом функции не определено. СМОТРИ ТАКЖЕ: подраздел 5.3.3, Sizeof, подраздел 5.7, Аддитивные операторы, подраздел 12.5, Бесплатный магазин и ISO C подпункт 7.1.6.

50

Согласно стандарту ISO C 1999 года (C99),size_t целочисленный тип без знака длиной не менее 16 бит (см. разделы 7.17 и 7.18.3).

Стандарт также рекомендуетsize_t не должен иметь целочисленный рейтинг конверсии больше, чемlong если возможно, т.е. кастингsize_t вunsigned long без проблем, если рекомендация соблюдается.

Стандарт ANSI C 1989 года (ANSI C) не упоминает минимальный размер или рекомендуемый уровень конверсии.

Стандарт ISO C ++ 1998 года (C ++ 98) (а также текущий проект для C ++ 0x) относится к стандарту C. Раздел 18.1 гласит:

The contents are the same as the Standard C library header <stddef.h> [...]

В соответствии с разделом 1.2 это означает библиотеку, определенную стандартом ISO C 1990 года (C90), включая первую поправку 1995 года (C95):

The library described in clause 7 of ISO/IEC 9899:1990 and clause 7 of ISO/IEC 9899/Amd.1:1995 is hereinafter called the Standard C Library.

Части относительноsize_t должны быть унаследованы от ANSI C: Frontmatter и нумерация разделов, стандарты для C90 и ANSI C идентичны. Мне нужна копия нормативной поправки, чтобы быть уверенным, что не было каких-либо соответствующих изменений вstddef.hНо я сомневаюсь в этом. Минимальный размер, кажется, вводится сstdint.hт.е. С99.

Пожалуйста, обратите внимание на следующую цитату из раздела 1.2 C ++ 98:

All standards are subject to revision, and parties to agreements based on this International Standard are encouraged to investigate the possibility of applying the most recent editions of the standards indicated below.

Да, но стандарт C ++ не ссылается на стандарт C99.
К сожалению, вопрос касается не C99, а C ++.
Почему-то я полагал, что стандарт C89 / C95 требует, чтобы size_t был как минимум 16 бит. Но похоже, что только C99 имеет это требование и что оно составляет по меньшей мере 65535.
@Neil, ну, он должен взять стандарт C, потому что ему делегирует стандарт C ++ :) Он сам не определяет size_t :)
Он говорит, что он ссылается на C99, но для библиотеки это относится к C90 и C95. В 1.2 / 2 говорится, что «библиотека, описанная в ... C90 и в ... C95, здесь и далее называется« Стандартная библиотека C ». Таким образом, когда он задает содержимое cstddef, он ссылается на C89 (и поправку C95, которая в переводе с TC на C89. Также как и C ++ 03 на C ++ 98) (другой раз, указанный в 17.4.1.2/4 )
5

В соответствии со стандартом он не подписан, однако я напоминаю, что некоторые старые реализации использовали тип со знаком для typedef.

Из старого документа GCC:

There is a potential problem with the size_t type and versions of GCC prior to release 2.4. ANSI C requires that size_t always be an unsigned type. For compatibility with existing systems' header files, GCC defines size_t in stddef.h to be whatever type the system's sys/types.h defines it to be. Most Unix systems that define size_t in sys/types.h, define it to be a signed type. Some code in the library depends on size_t being an unsigned type, and will not work correctly if it is signed

Я не уверен, насколько важно было бы защититься от этого. Мой код предполагает, что он не подписан.

Я думаю, что все знают, что он, вероятно, не подписан, но если кто-то не сможет процитировать соответствующий документ по стандартам, мы никогда не узнаем наверняка.
На данный момент у меня нет удобного стандартного документа (хотя я уверен, что все соответствующие стандарты, C90, C99 и C ++ 98 и выше, требуют его подписи). Тем не менее, я просто хотел отметить, что независимо от стандарта, есть потенциально важные исключения, где size_t является типом со знаком.
47

Yes, Это & APOS; susually определяется как что-то вроде следующего (в 32-битных системах):

typedef unsigned int size_t;

Ссылка:

Стандарт C ++ 18.1 определяетsize_t в<cstddef> который описан в стандарте C как<stddef.h>.
Стандарт C Раздел 4.1.5 определяетsize_t как беззнаковый целочисленный тип результатаsizeof оператор

Спасибо mehrdad за поиск ссылки peterchen
Ну, у меня есть стандарт C ++, но я не могу его найти, возможно, потому, что он фактически определен в стандарте C (не C99). Я надеюсь, что кто-то отыщет это, потому что я думаю, что это интересный вопрос!
пожалуйста, обратите внимание, чтоsize_t обычно будет 64-битным на 64-битных системах, тогда какint может быть 32-битным; такие вещи сильно зависят от компилятора
@litb: C ++ 2003, 27.6.2.5.2 определяет эти подписи. Обратите внимание, что первый блок - это функции-члены (т.е. не первый аргумент basic_ostream & amp;), в то время как последний блок - свободные функции. @ Mehrdad: C ++ 2003, 5.3.4, пар. 10: новое выражение передает количество пространства, запрошенное для функция выделения в качестве первого аргумента типа std :: size_t, такая же как вcplusplus.com/reference/std/new/operator%20new
@Neil: я знаю. Это было первое, что я нашел. У меня под рукой нет стандарта C ++, поэтому я загружаю его (мое соединение чертовски медленное). А пока я ставлю что-то кроме себя.
2

О, это просто ужасно

vector<MyObject> arr;
Fill(arr);
size_t size = arr.size();
for(size_t i = 1; i < size - 1; ++i)
{
  auto obj = arr[i];
  auto next = arr[i+1];
}

Теперь рассмотрим вариант использования, когда arr пуст.

Да, это. Но можете ли вы показать мне идиоматический способ, как приведенный выше код может быть исправлен? И, строго говоря, это не ответ на вопрос ОП.
14

Да, size_t гарантированно будет неподписанным типом.

Похожие вопросы