#c #function #gcc #types
#c #функция #gcc #типы
Вопрос:
У меня есть этот код:
#include <stdint.h>
void something(float a);
int main()
{
uint8_t a = 28;
something(a);
return 0;
}
void something(float a)
{
printf("%fn", a);
}
Я использую аналогичную функцию для записи переменных разных типов в файл, и я хотел бы получить сообщение об ошибке / предупреждении, поскольку я вызываю функцию something с неправильным типом аргумента (uint8_t вместо float).
Как я могу этого добиться?
Комментарии:
1. Код допустим, потому что a
uint8_t
может быть неявно преобразован в afloat
без потери значения.2.
How can I achieve this?
Почему бы не сделатьstruct something_arg { float a; }
, а затем потребоватьvoid something(struct something_arg arg)
?3. @dbush Я не получаю никаких предупреждений при использовании void something (uint8_t a); и передаче аргумента с плавающей запятой (за исключением предупреждения printf).
Ответ №1:
Старый школьный трюк заключается в том, чтобы изменить функцию на использование указателей, поскольку указатели в C имеют гораздо более строгие правила ввода, чем целые числа и числа с плавающей запятой.
#include <stdio.h>
#include <stdint.h>
void something(const float* a);
int main()
{
uint8_t a = 28;
/* gcc -std=c11 -pedantic-errors */
something(amp;a); // error: passing argument 1 of 'something' from incompatible pointer type
something(a); // error: passing argument 1 of 'something' makes pointer from integer without a cast
return 0;
}
void something(const float* a)
{
printf("%fn", *a);
}
Современная версия C:
#include <stdio.h>
#include <stdint.h>
void something_float (float a);
#define something(x) _Generic((x), float: something_float)(x)
int main()
{
uint8_t a = 28;
something(a); // error: '_Generic' selector of type 'unsigned char' is not compatible with any association
return 0;
}
void something_float (float a)
{
printf("%fn", a);
}
Комментарии:
1. Хорошее использование
_Generic
!2. Спасибо за это! Я никогда не сталкивался с _Generic и обязательно изучу его!
3. @godo Это было введено в C11, и в C17 были исправлены некоторые ошибки. Я бы рекомендовал использовать для этого последнюю версию gcc или clang.