GCC: разрешить перегруженные функции в C99 - PullRequest
2 голосов
/ 26 марта 2012

Я пишу код в C99 и компилирую через GCC. Я хотел бы использовать перегрузку функций по стилистическим соображениям (в противном случае мне пришлось бы самостоятельно выполнять манипулирование именами).

Я прочитал Есть ли причина, по которой C99 не поддерживает перегрузку функций? однако я все еще задаюсь вопросом, может ли она быть включена в GCC.

Можете ли вы помочь мне в этом вопросе?

Ответы [ 3 ]

10 голосов
/ 26 марта 2012

Нет, в C99 нет перегрузки функций, даже в глупых расширениях GCC.C11 добавляет _Generic, но даже тогда вам все равно придется самим искажать имена.

void foo_int(int x);
void foo_double(double x);

#define foo(arg) _Generic((arg), int: foo_int, double: foo_double)(arg)

Хорошо это или плохо.Это C.

4 голосов
/ 26 марта 2012

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

С C99 у вас уже есть возможность программировать макросы, которые в некотором смысле являются типичными. P99 имеет средства, которые облегчают его использование, например, для вызова такого макроса с другим количеством параметров. Чтобы определить, какую функцию вызывать в соответствии с конкретным параметром A, вы можете использовать что-то вроде (sizeof(A) == sizeof(float) ? sqrtf(A) : sqrt(A)).

Gcc имеет расширения, которые позволяют программировать такие вещи еще более удобно, а именно: блочные выражения с ({ any code here }) и typeof для объявления вспомогательных переменных того же типа, что и параметр макроса.

1 голос
/ 11 мая 2013

LLVM Clang3.3 ввел функцию перегрузки. На самом деле перегрузка функций может оказаться не такой простой, как вы ожидаете. Это связано с такими проблемами, как соглашение о вызове функций и ABI (Application Binary Interface). Когда вы смешиваете ваш код C с языком ассемблера, эти проблемы могут возникнуть. При работе с процедурами сборки имена экспортированных процедур не должны быть перегружены.

В LLVM Clang вы можете сделать это с атрибутом (перегружаемым):

static void __attribute__((overloadable)) MyFunc(float x)
{
    puts("This is a float function");
}

static int __attribute__((overloadable)) MyFunc(int x)
{
    puts("This is an integer function");
    return x;
}
...