Какое наибольшее значение sizeof (T) может дать? - PullRequest
8 голосов
/ 31 октября 2011

Сначала можно подумать std::numeric_limits<size_t>::max(), но если бы существовал такой огромный объект, мог бы он по-прежнему предлагать указатель «один за другим»?Я думаю, нет.Означает ли это, что наибольшее значение, которое может дать sizeof(T), составляет std::numeric_limits<size_t>::max()-1?Я прав или я что-то упустил?

Ответы [ 7 ]

3 голосов
/ 31 октября 2011

Если std::numeric_limits<ptrdiff_t>::max() > std::numeric_limits<size_t>::max(), вы можете вычислить размер объекта размером std::numeric_limits<size_t>::max(), вычтя указатель на него из указателя «один за другим».

Если sizeof(T*) > sizeof(size_t), у вас может быть достаточно различных указателей для адресации каждого байта внутри этого объекта (например, в случае, если у вас есть массив символов), плюс один для одного конца-конца.

Итак, можно написать реализацию, в которой sizeof может возвращать std::numeric_limits<size_t>::max(), и где вы можете получить указатель на один конец элемента такого большого размера.

3 голосов
/ 31 октября 2011

Q: Какое наибольшее значение sizeof (T) может дать?

A: std::numeric_limits<size_t>::max()

Очевидно, sizeof не может возвращать значение больше std::numeric_limits<size_t>::max(), так как оно не подходит. Единственный вопрос, может ли он вернуть ...::max()?

Да. Вот действительная программа, которая не нарушает никаких ограничений стандарта C ++ 03, которая демонстрирует доказательство на примере. В частности, эта программа не нарушает никаких ограничений, перечисленных в §5.3.3 [expr.sizeof] или в §8.3.4 [dcl.array]:

#include <limits>
#include <iostream>
int main () {
 typedef char T[std::numeric_limits<size_t>::max()];
 std::cout << sizeof(T)<<"\n";
}
2 голосов
/ 31 октября 2011

это не совсем четко определено.но чтобы оставаться в безопасных пределах стандарта, максимальный размер объекта составляет std::numeric_limits<ptrdiff_t>::max()

, потому что, когда вы вычитаете два указателя, вы получаете ptrdiff_t

, который является целочисленным типом со знаком

ура и hth.,

1 голос
/ 01 ноября 2011

Требование иметь возможность указывать за конец массива не имеет ничего общего с диапазоном size_t.Учитывая объект x, вполне возможно, что (&x)+1 может быть действительным указателем, даже если число байтов, разделяющих два указателя, не может быть представлено как size_t.

Можно утверждать, чтотребование действительно подразумевает верхнюю границу размера объекта с максимальным диапазоном указателей за вычетом выравнивания объекта.Однако я не верю, что в стандарте говорится, что такой тип не может быть определен;было бы просто невозможно создать его экземпляр и при этом оставаться соответствующим.

0 голосов
/ 31 октября 2011

Вы можете иметь стандартный совместимый компилятор, который учитывает размеры объектов, которые вызывают переполнение арифметики указателей; однако результат не определен. Из стандарта C ++, 5.7 [expr.add]:

Когда вычитаются два указателя на элементы одного и того же объекта массива, В результате разница индексов двух массивов элементы. Тип результата - это подпись, определяемая реализацией. интегральный тип; этот тип должен быть того же типа, который определен как std::ptrdiff_t в заголовке <cstddef> (18.2). Как и с любым другим арифметическое переполнение, если результат не помещается в предоставленное пространство, поведение не определено.

0 голосов
/ 31 октября 2011

A sizeof() выражение дает значение типа size_t. От стандарта С99 6.5.3.4:

Значение результата определяется реализацией, а его тип ( целочисленный тип без знака) это size_t, определенный в stddef.h (и других заголовки).

Следовательно, максимальное значение, которое sizeof () может дать SIZE_MAX.

0 голосов
/ 31 октября 2011

Если бы это был тест, я бы сказал, (size_t) -1

...