c语言有多个重载函数fabs,C是否支持重载?

C标准中没有关于操作符重载的规定。基于许多构建系统无法容纳具有相同名称的多个功能的建议,拒绝添加该提议。尽管C ++可以通过以下方法解决此问题:

void foo(int);

int foo(char*);

long foo(char *, char **);

编译为诸如v__foo_i,i__foo_pc和l__foo_pc_ppc之类的函数[编译器使用不同的命名约定,尽管C ++标准禁止在标识符中使用内部双下划线,以便允许编译器以类似的方式给出类似上面的名称]。C标准的作者不希望要求任何编译器更改命名约定以允许重载,因此他们不提供此规范。

对于编译器来说,允许静态和内联函数的重载而不产生命名问题将是可能且有用的。实际上,这将与允许重载外部可链接函数一样有用,因为一个人可能具有头文件:

void foo_zz1(int);

int foo_zz2(char*);

long foo_zz3(char *, char **);

inline void foo(int x) { foo_zz1(x); }

inline int foo(char* st) { foo_zz2(st); }

long foo(char *p1, char **p2) { foo_zz3(p1,p2); }

我记得在看一个嵌入式编译器,用于C和C ++之间的混合,它支持上述作为非标准扩展,但是我对细节并不满意。无论如何,即使某些C编译器确实支持不具有外部链接的函数的重载,C14也不支持它,我也不知道(不幸地)有任何积极的努力将这种功能添加到将来的C标准中。

但是,可以使用宏使GCC支持某种形式的重载,而运算符重载的语言不直接支持这种形式的重载。GCC包含一个内在函数,它将识别表达式是否可以作为编译时常量进行评估。使用此内在函数,可以编写一个宏,该宏可以根据参数以不同的方式(包括通过调用函数)对表达式求值。这在某些情况下很有用,在这种情况下,如果给定一个编译时常量参数,则该公式将被视为一个编译时常量,但如果给定一个变量参数,则将导致可怕的混乱。举一个简单的例子,假设希望对32位值进行位反转。如果该值是常数,则可以通过以下方式实现:

#define nyb_swap(x) \

((((x) & 1)<<3) | (((x) & 2)<<1) | (((x) & 4)>>1) | ((((x) & 8)>>3) )

#define byte_swap(x) \

( (nyb_swap(x)<<4) | nyb_swap((x) >> 4) )

#define word_swap(x) \

( (byte_swap(x)<<24) | (byte_swap((x) >> 8)<<16) | \

(byte_swap((x) >> 16)<<8) | (byte_swap((x) >> 24)) )

像uint32_t x=word_swap(0x12345678);这样的表达式将简单地加载x0x87654321。另一方面,如果该值不是一个常数,则结果将是可怕的:像这样的表达式uint32_t y=word_swap(x);可能会生成许多指令;调用具有部分展开的循环的函数几乎一样快,但是紧凑得多。另一方面,使用循环会防止将结果视为编译时常数。

使用GCC,可以定义一个宏,该宏将在给定常量的情况下使用产生常量的宏,或者在给定变量的情况下调用函数:

#define wswap(x) \

(__builtin_constant_p((x)) ? word_swap((x)) : word_swap_func((x))

这种方法不能完成基于类型的重载可以做的所有事情,但是它可以完成许多重载不能做的事情。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值