Выдает ошибку / предупреждение при предоставлении неправильного типа аргумента функции C

#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 может быть неявно преобразован в a float без потери значения.

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.