2010-03-10 1 views
3

Это мое предупреждение.C memset warning

warning: passing argument 2 of ‘memset’ makes integer from pointer without a cast 

Тогда я изменена следующим образом (NULL, чтобы к 0)

Before Change : memset(key, NULL, KEY_BYTES); 
After Change : memset(key, 0, KEY_BYTES); 

Предупреждение удаляется.

Я использую linux & gcc-компилятор, C.

Является ли это правильное действие

+4

Не используйте NULL, если вы имеете в виду 0. – 2010-03-10 06:11:42

+1

NULL! = NUL (еще 4) –

ответ

1

Да, они имеют тот же эффект. Компилятор должен обрабатывать NULL как специальный указатель NULL (тогда как некоторые более примитивные компиляторы просто #define NULL 0), а второй параметр memset имеет тип int, поэтому, изменив его на 0, вы используете нулевое значение, но удовлетворяющее требованию int.

+0

'#define NULL 0' не является« более примитивным ». Это стандарт C++, поэтому '(void) 0' даже не разрешен в C++. В C, '(void) 0' больше используется/более std соответствует. – sbi

+1

@sbi У вас отсутствует звездочка: (void *) 0 –

+0

@Charlie: Конечно. Извините за эту глупую ошибку. В любом случае, я думаю, что я прав. – sbi

3

Возможно, NULL определяется как ((void *) 0). Обе версии работают правильно, но вторая выглядит лучше - memset требует числа, а не указателя.

13

В зависимости от реализации, стандартная библиотека C иногда определяет NULL как нулевое целое число (что позволит избежать предупреждения, которое вы видели), но иногда определяет NULL как нулевое преобразование в указатель пустоты. Последняя реализация вызывает предупреждение, которое вы видели.

Чтобы ответить на ваш конкретный вопрос, вы не должны использовать NULL в этом случае. Независимо от реализации, NULL предназначен для использования в качестве нулевого указателя, а не для синонима целого нуля. Если вы хотите использовать memset, чтобы заполнить блок памяти нулями, то в качестве второго аргумента передайте ноль, а не NULL.

Цитируя http://en.wikipedia.org/wiki/Stdlib.h:

NULL

В stdlib.h и stddef.h файлы заголовки определяют Нулевые макросъемки, что дает нулевой указатель постоянная, и представляет собой значение указателя что не будет указывать на действительный адрес .

Варианты

NULL, может быть определен как константного выражения, равной нулю Int, Int длинный ноль, или нулевой приведение к пустоте * Указатель:

#define NULL 0
#define NULL 0L
#define NULL ((void *) 0)

Хотя константа нулевого указателя всегда равна , представленный в C символьным номером константой 0 или 0, отличной от указателя , фактическое представление битов такого указателя является системным и может содержать один бит.

3

Второй параметр для memset имеет тип int.NULL находится в C. константа пустого указателя Согласно стандарту:

Целое константы со значением 0, или такого выражением приводится к типу void *, называется постоянной пустого указателя.

Таким образом, NULL может быть определено как (void *)0 или его эквивалент. В таком случае ваш звонок memset неверен, потому что вы конвертируете указатель в целое число.

Другой способ в порядке: если вы используете 0, где ожидается нулевой указатель, компилятор выполнит преобразование для вас. Таким образом, учитывая тип T следующие наборы как p и q к нулевому указателю:

T *p = NULL; 
T *q = 0; 

Кроме того, данный указатель p, эквивалентны следующие:

if (p) ... 
if (p != NULL) ... 
if (p != 0) ... 

Это потому, что 0 является special: в контекстах указателя он автоматически преобразуется в константу нулевого указателя. Указатель, с другой стороны, никогда не преобразуется в целое число неявно. Любое целое число, отличное от 0, также никогда не преобразуется в указатель неявно.

Наконец, в коде ниже, даже если i имеет значение 0, это не пустой константный указатель в присвоении p:

int i = 0; 
int *p = i; 

выше вызовет предупреждение при компиляции в совместимом режиме ,

(Выше немного экскурса, но я надеюсь, что это не совсем по теме.)

0

MemSet принимает второй аргумент в качестве символа не любой pointer.In первого звонка, вы передаете NULL который является указателем, ничего не указывает на C. Вот почему, он дал ошибку. Во втором вызове вы присваиваете 0 байт памяти.

0

При использовании memset(key, NULL, KEY_BYTES); NULL is the (void*)0 {ie; void* typecasted of int zero}. and the memset 2nd argument should be of type "unsigned int" Именно поэтому он показывает предупреждение.

В зависимости от используемого вами компилятора он будет вести себя. Использование gcc сделает предупреждение (относительно типа данных) и просто примет ближайшее возможное доступное значение из заданного значения аргумента.

 Смежные вопросы

  • Нет связанных вопросов^_^