我用C99编写代码并通过GCC编译。出于风格原因,我想使用函数重载(否则我必须自己进行名称修改)。
我已经阅读了C99不支持函数重载有什么原因吗?但是,我仍然想知道是否可以在GCC中启用它。
此时你能帮我吗?
不,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。
C 中的宏可以部分替代其他语言的函数重载。正如 Cat Plus Plus 在她的回答中指出的那样,C11 有额外的构造
_Generic
来编程类型通用宏。
使用 C99,您已经可以编写某种意义上的通用宏。 P99 具有简化使用的功能,例如使用不同数量的参数调用此类宏。要根据特定参数来区分要调用哪个函数
A
,您可以使用类似 (sizeof(A) == sizeof(float) ? sqrtf(A) : sqrt(A))
的内容。
Gcc 具有允许更轻松地进行此类编程的扩展,即使用
({ any code here })
和 typeof
的块表达式来将相同类型的辅助变量声明为宏参数。
LLVM Clang3.3引入了函数重载。事实上,函数重载可能不像你想象的那么容易。它涉及到函数调用约定和ABI(应用程序二进制接口)等问题。当您将 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;
}
struct core * __must_check getAnyCore(unsigned long v,...) {
va_list ap;
struct core *c = NULL;
va_start(ap, v);
switch (v) {
case sizeof(struct device):
c = (va_arg(ap, struct device *))->c;
break;
case sizeof(struct driver):
c = (va_arg(ap, struct driver *))->c;
break;
default:
c = NULL;
break;
}
va_end(ap);
return c;
}
#define getCore(obj) getAnyCore(sizeof(*obj),obj)
我通过这种方式实现了C的重载,但限制是'struct device'和'struct driver'的大小不一致。