Я видел два стиля использования sizeof
для операций, связанных с памятью (например, в memset
или malloc
):
sizeof(type)
, а такжеsizeof variable
илиsizeof(variable)
Какой из них вы бы предпочли, или вы бы использовали сочетание двух стилей, и когда бы вы использовали каждый стиль? Каковы плюсы и минусы каждого стиля и когда вы их используете?
В качестве примера я вижу следующую пару ситуаций, когда один стиль помогает, а другой нет:
Если вы неправильно указали косвенность указателя:
type *var;
...
memset(var, 0, sizeof var); /* oops */
Когда тип меняется:
new_type var; /* changed from old_type to new_type */
...
memset(&var, 0, sizeof(old_type)); /* oops */
c
coding-style
congusbongus
источник
источник
array
это действительно массив C, тоsizeof(array)
возвращает количество байтов, необходимое для хранения элементов массива , Еслиarray
указатель на первый элемент распавшегося массива Си, то ваше утверждение выполнено. Передача массива C в качестве аргумента функции делает его похожим на указатель в функции - вся информация, доказывающая, что это был массив, как и его размер, теряется. Вот почему это распалось . Неправильно 2: «массивы на самом деле не существуют в C; ... просто синтаксический сахар для указателей».Предпочтение (как всегда) должно отражать ваше намерение как можно более прямо.
Намерение работать против памяти существующей переменной? Если это так, то используйте
sizeof(variable)
, так как это как можно более точно показывает, что вам важна память самой переменной.Есть ли намерение выполнить какой-то расчет для типа, например, чтобы определить, сколько памяти должно быть выделено для нового экземпляра? Если так, то используйте
sizeof(type)
.То есть я предпочитаю
над
поскольку последний случай выглядит так, как будто вы пытаетесь получить доступ к переменной, которая еще не существует.
С другой стороны, я предпочитаю
над
поскольку намерение состоит в том, чтобы явно заполнить нулем содержимое переменной, поэтому мы должны оперировать этой переменной. Попытка использовать метаданные типа просто сбивает с толку, здесь.
источник
void *
они автоматически приводятся к другим типам указателей, чтобы быть ошибочным.Я бы предпочел
sizeof(type)
болееsizeof variable
. Несмотря на то, что заставляет вас беспокоиться больше о типе и сделать больше изменений, это поможет вам избежать указателя ошибки, косвенного предоставления которых входят в число наиболее распространенных причин ошибок в C .Я бы не стал так сильно беспокоиться об ошибках, когда тип
sizeof(type)
меняется; всякий раз, когда вы меняете тип переменной, вы должны выполнить быстрое сканирование, чтобы увидеть, где эта переменная используется и нужно ли вам изменять какие-либоsizeof(type)
операторы. Несмотря на то, что всегда есть вероятность ошибиться, риск намного ниже, чем ошибки косвенного указателя.Одним из преимуществ
sizeof variable
является использование массивов, но на практике я обнаружил, что передача массивов в виде пар first / len гораздо более распространена (в этом случае просто используется длина), плюс также очень легко получить неправильный размер из-за распад массива / указателя, как в этом примере:источник
sizeof var
; если это указатель, то этоsizeof *var
. Это также то, что люди могут ошибаться, и компилятор с радостью примет это без жалоб. Я утверждаю, что эти ошибки гораздо сложнее обнаружить, и они встречаются чаще, чем ошибки сsizeof(type)
формой.C
, публикация кода на C более информативна, чем на C ++mat3_t::mat3_t(...)
.Цель состоит в том, чтобы удалить избыточность. Если вы используете sizeof для операции, связанной с переменной, то, очевидно, вы должны отразить это в sizeof. Да, вы можете испортить, как в первом примере, но лекарство не использует тип, а * var, правильно соответствующий цели.
Чтобы смягчить такие проблемы, обычно используют макросы, шаблоны и аналогичные инструменты, подготовленные для данного варианта использования, а не «голый размер».
Посмотрите мой макрос CLEAR, который используется исключительно вместо голого memset. Спасла мою задницу несколько раз в случаях опечатки косвенного действия или когда содержимое структуры подобрало вектор или строку ...
источник
Бизнес логика определяет ваш выбор.
Если ваш код ссылается на конкретную переменную и без этой переменной ваш код не имеет смысла - выберите
sizeof(var)
Если код имеет дело с набором переменных определенного типа - выберите
sizeof(type)
. Обычно это нужно, если у вас естьtypedef
переменная, которая определяет много переменных, которые вы обрабатываете по-разному в зависимости от их типа (например, сериализация). Вы можете не знать, какая из этих переменных останется в будущих версиях кода, поэтому выбор типа в качестве аргумента является логически правильным. Даже изменение такогоtypedef
не повлияет на ваш размер строки.источник
В зависимости от цели sizeof (переменная) может быть лучшим решением. Таким образом, вы можете при необходимости изменить тип переменной, не исправляя все записи для этого типа. Но опять же, это зависит от вашей цели.
источник