Каковы аргументы против использования size_t? - PullRequest
3 голосов
/ 27 сентября 2011

У меня есть такой API,

class IoType {
......
    StatusType writeBytes(......, size_t& bytesWritten);
    StatusType writeObjects(......, size_t& objsWritten);
};

Кажется, у старшего члена команды, которого я уважаю, есть проблема с типом size_t, и он предлагает мне использовать типы C99. Я знаю, это звучит глупо, но я всегда думаю, что типы c99, такие как uint32_t и uint64_t, выглядят ужасно. Я использую их, но только когда это действительно необходимо, например, когда мне нужно сериализовать / десериализовать структуру, я хочу быть точным в отношении размеров моих элементов данных.

Какие аргументы против использования size_t? Я знаю, что это не настоящий тип, но если я точно знаю, что для меня достаточно даже 32-разрядного целого числа, а тип размера кажется подходящим для количества байтов или количества объектов и т. Д.

Ответы [ 3 ]

4 голосов
/ 27 сентября 2011

Используйте типы точного размера, например uint32_t, всякий раз, когда вы имеете дело с сериализацией любого рода (двоичные файлы, работа в сети и т. Д.).Используйте size_t всякий раз, когда вы имеете дело с размером объекта в памяти - для этого он и предназначен.Все функции, имеющие дело с размерами объектов, такие как malloc, strlen и оператор sizeof all size_t.

Если вы правильно используете size_t, ваша программа будет максимально переносимой, и это не будет тратить время и память на платформах, где это не нужно.На 32-битных платформах size_t будет 32-битным - если вы вместо этого используете uint64_t, вы бы потратили время и пространство.И наоборот, на 64-битных платформах size_t будет 64-битным - если вы вместо этого используете uint32_t, ваша программа может работать неправильно (возможно, даже аварийно завершить работу или открыть уязвимость системы безопасности), если ей когда-либо придется иметь делоОбъем памяти больше 4 ГБ.

0 голосов
/ 27 сентября 2011

Я не могу придумать ничего плохого в использовании size_t в тех случаях, когда вам не нужно сериализовать значения. Также правильное использование size_t повысит безопасность / переносимость кода для 32- и 64-разрядных шаблонов.

0 голосов
/ 27 сентября 2011

Хм, не стоит заменять size_t (максимально переносимая вещь) на менее переносимый тип C99 фиксированного или минимального размера без знака.

С другой стороны, вы можете избежать многихтехнических проблем (потерянное время), используя вместо этого подписанный тип ptrdiff_t.Стандартная библиотека использует тип unsigned только по историческим причинам.Это имело смысл в свое время, и даже сегодня, для 16-битных архитектур, но, как правило, это не что иное, как проблемы и многословие.

Внесение этого изменения требует некоторой поддержки, в частности aобщая size функция , которая возвращает размер массива или контейнера как ptrdiff_t.


Теперь, что касается подписи вашей функции
    StatusType writeBytes(......, size_t& bytesWritten);

Это заставляет выбрать тип вызывающего кода для числа записанных байтов.

И затем, с типом без знакаsize_t принудительно, легко ввести ошибку, например, проверив, является ли она меньше или больше некоторой вычисленной величины.

Гротескный пример: std::string("ah").length() < -5 гарантировано true.

Итак, вместо этого сделайте это…

    Size writeBytes(......);

или, если вы не хотите использовать исключения,

    Size writeBytes(......, StatusType& status );

Допустимо перечисление возможных состояний в качестве типа без знакаили как угодно, потому что единственными операциями над значениями состояния будут проверка на равенство и, возможно, в качестве ключей.

...