Кто-то использует имя структуры в качестве имени переменной также. Что действительно говорит код?

Этим утром мы нашли старый блок кода, который заставлял вызов библиотеки отказывать.

struct   fred
{
    int     a;
    int     b;
    int     c;
};

fred     fred[MAX_SIZE+1];

memset( fred, 0, sizeof(fred) * MAX_SIZE+1 );

Кажется, что sizeof (fred), возможно, был полным размером массива, а не размером структуры, поскольку это перезаписывало большую память.

То, что это скомпилировало, не предупреждая о нескольких различных системах, казалось нечетным.

Существует ли корректное семантическое для этого случая, где имя типа и имя переменной сталкиваются? или это своего рода неопределенное поведение? или просто дефект?

11
задан Lightness Races with Monica 10 January 2013 в 15:10
поделиться

4 ответа

Номер один, не делайте этого, это сбивает с толку - но вы уже это обнаружили.

Переменная скрывает имя структуры, но вы все равно можете использовать struct fred для ссылки на тип.

например.

fred     fred[MAX_SIZE+1];

memset( fred, 0, sizeof(struct fred) * (MAX_SIZE+1) );

В качестве альтернативы, почему бы просто не использовать размер всего объекта. Таким образом, ваш вызов memset устойчив к изменениям размера или типа массива. Вы можете сделать:

memset( fred, 0, sizeof fred );

Вы должны иметь круглые скобки при использовании идентификатора типа с sizeof , но это не требуется при использовании объекта.

14
ответ дан 3 December 2019 в 06:20
поделиться

Разве это не должно быть sizeof ( fred) * (MAX_SIZE + 1), так как ваш массив имеет длину MAX_SIZE + 1?

2
ответ дан 3 December 2019 в 06:20
поделиться

Также имейте в виду, что если ваш сервер IIS сжатие вывода с помощью GZIP, то будет казаться, что все вызовы Response.Flush игнорируются.

Это включено по умолчанию в IIS7 и Windows 7.

И, если вы тестируете с Fiddler, не забудьте включить режим Streaming, иначе Fiddler соберет сброшенный HTML-код и будет удерживать его до тех пор, пока соединение не будет установлено.

-1 21 --- 4780792-

За исключением случаев, размер которых зависит от времени выполнения, типичный идиоматический способ использования memset (а также memcpy , malloc ] и т. д.) должно выполняться

memset(dst_ptr, 0, sizeof *dst_ptr);

или, что то же самое,

memset(&dst_object, 0, sizeof dst_object);

Как это должно было быть использовано и в этом случае

memset(&fred, 0, sizeof fred);

, и проблема с конфликтом имен не возникла бы. Вариант memset (fred, 0, sizeof fred) также будет работать.

0
ответ дан 3 December 2019 в 06:20
поделиться

Когда вы определяете переменную, она скрывает имя типа, так что да, когда вы делаете sizeof (fred) , вы получаем размер массива, а не размер структуры. в этом довольно легко убедиться, просто распечатав sizeof (fred) .

Краткий ответ, однако, прост: «Не делай этого».

1
ответ дан 3 December 2019 в 06:20
поделиться
Другие вопросы по тегам:

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