Это неопределенное поведение? Соответствующие части стандарта мало что говорят.
size_t n = SIZE_MAX / sizeof(double) + 1;
size_t m = sizeof(double[n]);
Это неопределенное поведение? Соответствующие части стандарта мало что говорят.
size_t n = SIZE_MAX / sizeof(double) + 1;
size_t m = sizeof(double[n]);
В стандарте C явно не указано, что типа size_t
достаточно для работы с размерами всех объектов или типов, особенно для гипотетических типов, экземпляры которых на самом деле не созданы.
В C 2018 7.19 2 стандарт говорит, что size_t
«является беззнаковым целым типом результата оператора sizeof». Это говорит нам о типе size_t
, но не о значениях, которые могут возникнуть во время вычислений. В 5.2.4 стандарт признает, что реализации C обязательно имеют ограничения и что они должны ломаться в различных точках.
7.19 4 гласит: «Типы, используемые для size_t
и ptrdiff_t
, не должны иметь целочисленный ранг преобразования выше, чем у signed long int
, если только реализация не поддерживает объекты, достаточно большие, чтобы сделать это необходимым». Это подтверждает наше желание, чтобы size_t
мог представлять размеры всех поддерживаемых объектов, особенно потому, что это подразумевает, что существование объекта делает «необходимым» то, что size_t
может представлять его, но это не явное утверждение, что size_t
должен сделать это, и это не относится к гипотетическим типам, которые могут быть описаны, но не могут быть реализованы как объекты.
Если бы мы вычислили n * sizeof(double)
, мы узнали бы результат: 6.2.5 9 говорит: «Вычисление, включающее операнды без знака, никогда не может переполниться, потому что результат, который не может быть представлен результирующим целочисленным типом без знака, уменьшается по модулю числа, которое на единицу больше, чем наибольшее значение, которое может быть представлено результирующим типом». Однако с sizeof(double[n])
не совсем ясно, что это применимо, потому что, хотя n
не имеет знака, это не прямой операнд sizeof
, где происходит вычисление результата, который не может быть представлен. Стандарт явно не говорит нам, что результат этого sizeof
будет уменьшаться таким же образом.
Таким образом, эта операция не покрывается стандартом C.
size_t
может хранить максимальный размер теоретически возможного объекта любого типа (включая массив).
- person Ayxan Haqverdili; 03.09.2019
sizeof(double[SIZE_MAX/sizeof(double) + 1])
, но я думаю, что лучше рассматривать это как нечто, что комитет C не учел, а не что-то, что, по решению комитета, должно быть неопределенным. (Кроме того, я не уверен, что эта фраза хорошо понята. Многие люди, кажется, рассматривают ее как поведение, которое вы должны избегать, но это несовместимо со многими законными расширениями C.)
- person Eric Postpischil; 03.09.2019
sizeof(double[SIZE_MAX]);
- person M.M   schedule 03.09.2019