GCC:允许在C99中使用重载函数

4
我使用C99编写代码,并通过GCC进行编译。出于样式原因,我想使用函数重载(否则我必须自己进行名称混淆)。
我已阅读 C99不支持函数重载的原因是什么? 然而,我仍然想知道是否可以在GCC中启用它。
你能帮我吗?

1
一个简单的解决方法是使用C++而不是C。此外,重载需要名称修饰,在C++中存在但在C中不存在。因此,C++实际上是你的关键。 - Al Kepp
什么是CGG?如果您想要高级语言特性,例如函数重载,那么您应该考虑更适合的语言,比如C++。 - Paul R
世界和我们的机器已经准备好了一个不需要链接器的C版本!进步。这绝对使它领先于C++的人们。 - Hans Passant
1
我猜 CGG 是对 GCC 的拼写错误? - Kyle
1
函数指针表。搞定,完成。 - tbert
看这篇文章:https://dev59.com/GloV5IYBdhLWcg3wPcxv 这不太好看,但是确实可行。 - tjwrona1992
4个回答

11
不,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 语言。


最接近我所寻找的功能。 - shuhalo
这不是真的。使用“愚蠢”的GCC扩展,函数重载是可能的。请参阅此帖子:https://dev59.com/GloV5IYBdhLWcg3wPcxv - tjwrona1992
1
我链接的解决方案适用于C99。你说在C99中不可能实现。 - tjwrona1992
好在有人在2016年关注那些可怜的C99用户! - Cat Plus Plus
2
有人必须要做。 ;) 另外,那就是原帖所询问的内容。 - tjwrona1992

4
在C语言中,宏定义可以部分地取代其他编程语言中的函数重载。Cat Plus Plus在她的答案中指出,C11还有额外的构造_Generic来编写类型通用宏。
使用C99,您已经有了一些可以编写某种意义上为类型通用的宏的可能性。P99提供了方便的工具,例如调用不同数量参数的宏。要区分根据特定参数A调用哪个函数,则可以使用类似于(sizeof(A) == sizeof(float) ? sqrtf(A) : sqrt(A))的语句。
Gcc有扩展功能,可以更加舒适地编写此类代码,即使用带有({ any code here })的块表达式以及typeof来声明与宏参数相同类型的辅助变量。

你为什么认为@CatPlusPlus是女性? - rubenvb
1
我为什么要假设它是“他”呢?(但也许我受到了母语的影响,因为“猫”是女性性别。) - Jens Gustedt
@JensGustedt 嘿,在法语中,“猫”是阳性的。如果你用阴性形式说,可能会说出一些不太礼貌的话... - user1284631

3
LLVM Clang3.3引入了函数重载。实际上,函数重载可能并不像你想象的那么容易。它涉及到诸如函数调用约定和ABI(应用程序二进制接口)等问题。当你将C代码与汇编语言混合使用时,这些问题可能会出现。
当你使用汇编过程时,导出过程的名称不应该被重载。
在LLVM Clang中,你可以使用属性(overloadable)来实现这一点。
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;
}

0
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'的大小不一致。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接