Проверка типов с помощью макроса - PullRequest
0 голосов
/ 20 мая 2018

Я нашел этот код, и я понимаю, что он делает (печатает, если var имеет тип float ), но я не могу понять, как:

#include <stdio.h>
#include <stdlib.h>

#define typename(x) _Generic((x), float: "float")

#define isCompatible(x, type) _Generic(x, type: true, default: false)

int main(){
  float var; 
  if(isCompatible(var, float))
    printf("var is of type float!\n");
}

Что такое имяТипа (х) ?Почему никогда не называется?Также я не могу понять эту конструкцию:

_Generic(x, type: true, default: false)

И здесь есть способ не передавать float в качестве параметра и делать его неявным?

if(isCompatible(var, float))

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Почему typename никогда не вызывается - это вопрос, который вы должны задать разработчику кодового фрагмента ...

Ключевое слово _Generic является функцией C11.Идея состоит в том, чтобы генерировать различный код в зависимости от типа переменной.

C не имеет оператора typeof, подобного Java, таким образом, то, что в Java выглядит как

...
if(typeof(p) == typeof(double)) {
    System.out.println("Got type 1");
} 
if(typeof(p) == typeof(char)) {
     System.out.println("Got type 2");
}
...

, может бытьдостигается через _Generic в C11 через

#include <stdio.h>

#define PRINT_MY_TYPE_NUMBER(x) _Generic((x), \
    double: printf("Got type 1\n"),\
    char: printf("Got type 2\n") \
)

int main(int c, char** v) {

    double p = 10;

    PRINT_MY_TYPE_NUMBER(p));

}

Примечание : _Generic не поддерживает произвольные, а только «простые» типы.

Идея isCompatible(variable, type) возвращает true, если variable имеет тип, совместимый с type.Это зависит от того, будет ли передано type, и, следовательно, оно будет передано type, поэтому неявно переданное type сделает isCompatible бесполезным ИМХО.

0 голосов
/ 20 мая 2018

Я подозреваю, что вы хотите посмотреть документацию по _Generic здесь - это функция C11 (стандарт C11 (ISO / IEC 9899: 2011) s 6.5.1.1 Выбор общего типа (p: 78-79)) .См. Также принятый ответ здесь .

По сути, в этом примере макрос isCompatible вызывает _Generic и (через type: true) возвращает true, если x (первый аргумент) совместим с типом type, иначе false.

Макрос typename не используется, но возвращает текст float, если аргумент совместим с float.Почему что-то определено, но не используется, вы должны спросить у автора кода.

...