По сути, вам нужно для приведения аргументов к функциям, которые ожидают параметр, отличный от утверждений их прототипа.
Например, isalpha()
имеет прототип с аргументом int
, но на самом деле ожидает unsigned char
.
char *p;
if ((*p != EOF) && isalpha((unsigned char)*p) /* cast needed */
{
/* ... */
}
И вы должны быть особенно осторожны с функциями, которые принимают переменное число аргументов, например:
long big;
printf("%d\n", (int)big);
Редактировать
Компилятор не может преобразовать аргументы переменных функций в правильный тип, поскольку в самом прототипе нет информации о типе. Рассмотрим функцию, похожую на printf ()
int my_printf(const char *fmt, ...);
Насколько известно компилятору, вы можете передавать значения всех типов в аргументе "...", и вы должны убедиться, что аргументы соответствуют ожидаемой функции. Например, скажем, функция my_printf()
принимает значение типа time_t
с соответствующим спецификатором "% t" в строке формата.
my_printf("UNIX Epoch: %t.\n", 0); /* here, 0 is an int value */
my_printf("UNIX Epoch: %t.\n", (time_t)0); /* and here it is a time_t */
Мой компилятор не хочет, чтобы этот сбой! Очевидно, он ( и тот, что на кодовой панели тоже ) передает 8 байтов для каждого аргумента в "..."
Используя прототип без "..." (int my_printf(const char *fmt, time_t data);
), компилятор автоматически преобразует первый 0 в правильный тип.
Примечание: некоторые компиляторы (включая gcc) будут проверять аргументы против строки формата для printf()
, если строка формата является литеральной строкой