C语言 C 是否支持重载?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2351792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:40:34  来源:igfitidea点击:

Does C support overloading?

c

提问by J.K.Aery

I just want to know if C supports over loading? As we use system functions like printf with different no of arguments. Help me out

我只想知道 C 是否支持重载?因为我们使用系统函数,比如 printf 和不同的参数。帮帮我

采纳答案by Steve Jessop

No, C doesn't support any form of overloading (unless you count the fact that the built-in operators are overloadedalready, to be a form of overloading).

不,C 不支持任何形式的重载(除非您将内置运算符已经重载的事实视为重载的一种形式)。

printfworks using a feature called varargs. You make a call that lookslike it might be overloaded:

printf使用名为 varargs 的功能工作。您拨打的电话看起来可能已超载:

printf("%d", 12); // int overload?
printf("%s", "hi"); // char* overload?

Actually it isn't. There is only one printf function, but the compiler uses a special calling convention to call it, where whatever arguments you provide are put in sequence on the stack[*]. printf (or vprintf) examines the format string and uses that to work out how to read those arguments back. This is why printf isn't type-safe:

其实不是。只有一个 printf 函数,但编译器使用一种特殊的调用约定来调用它,您提供的任何参数都按顺序放在堆栈 [*] 上。printf(或 vprintf)检查格式字符串并使用它来计算如何读回这些参数。这就是 printf 不是类型安全的原因:

char *format = "%d";
printf(format, "hi"); // undefined behaviour, no diagnostic required.

[*] the standard doesn't actually saythey're passed on the stack, or mention a stack at all, but that's the natural implementation.

[*] 标准实际上并没有它们是通过堆栈传递的,或者根本没有提到堆栈,但这是自然的实现。

回答by Ken

C does not support overloading. (Obviously, even if it did, they wouldn't use that for printf: you'd need a printf for every possible combination of types!)

C 不支持重载。(显然,即使这样做,他们也不会将它用于 printf:对于每种可能的类型组合,您都需要一个 printf!)

printf uses varargs.

printf 使用可变参数

回答by codaddict

No, C does not support overloading, but it does support Variadic functions. printf is an example of Variadic functions.

不,C 不支持重载,但它支持Variadic 函数。printf 是可变参数函数的一个例子。

回答by AnT

It all depends on how you define "support".

这完全取决于您如何定义“支持”。

Obviously, C language provides overloaded operatorswithin the core language, since most operators in C have overloaded functionality: you can use binary +with int, longand with pointer types.

显然,C 语言在核心语言中提供了重载运算符,因为 C 中的大多数运算符都具有重载功能:您可以将二进制+intlong和指针类型一起使用。

Yet at the same time C does not allow you to create your own overloaded functions, and C standard library also has to resort to differently-named functions to be used with different types (like abs, fabs, labsand so on).

然而,在同一时间C不允许你创建你自己的重载函数和C标准库也有诉诸不同名称的功能与不同类型(如使用absfabslabs等)。

In other words, C has some degree of overloading hardcoded into the core language, but neither the standard library nor the users are allowed to do their own overloading.

换句话说,C 有一定程度的重载硬编码到核心语言中,但标准库和用户都不允许进行自己的重载。

回答by Magarshak

No, C doesn't support overloading. If you want to implement overloading similar to C++, you will have to mangle your function names manually, using some sort of consistent convention. For example:

不,C 不支持重载。如果要实现类似于 C++ 的重载,则必须使用某种一致的约定手动修改函数名称。例如:

int myModule_myFunction_add();
int myModule_myFunction_add_int(int);
int myModule_myFunction_add_char_int(char, int);
int myModule_myFunction_add_pMyStruct_int(MyStruct*, int);

回答by Pete Kirkham

Not directly, and this is not how printfworks, but it is possible to create the equivalent of overloaded functions using macros if the types are of different sizes. The type-generic math functions in tgmath.hof the C99 standard may be implemented in that manner.

不是直接的,这不是printf工作原理,但是如果类型具有不同的大小,则可以使用宏创建等效的重载函数。C99 标准的tgmath.h中的类型通用数学函数可以以这种方式实现。

回答by supercat

There is no provision in the C standard for operator overloading; proposals to add it have been rejected on the basis that many build systems have no facility to accommodate multiple functions with the same name. While C++ can work around this by e.g. having

C 标准中没有关于运算符重载的规定;添加它的提议已被拒绝,因为许多构建系统无法容纳具有相同名称的多个功能。虽然 C++ 可以通过例如拥有

void foo(int);
int foo(char*);
long foo(char *, char **);

compile to functions named something like v__foo_i, i__foo_pc, and l__foo_pc_ppc [compilers use different naming conventions, though the C++ standard forbids the use of internal double-underscores in identifiers so as to allow compilers to give things names like the above without conflict]. The authors of the C standard did not want to require any compilers to change naming conventions to allow for overloading, so they don't provide for it.

编译为类似于 v__foo_i、i__foo_pc 和 l__foo_pc_ppc 的函数[编译器使用不同的命名约定,尽管 C++ 标准禁止在标识符中使用内部双下划线,以便允许编译器在不发生冲突的情况下给出类似上面的名称]。C 标准的作者不想要求任何编译器更改命名约定以允许重载,因此他们没有提供它。

It would be possible and useful for a compiler to allow overloading of static and inline functions without creating naming problems; this would in practice be just as useful as allowing overloading of externally-linkable functions since one could have a header file:

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

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); }

I recall looking at an embedded compiler for a hybrid between C and C++ which supported the above as a non-standard extension, but I'm not positive about the details. In any case, even if some C compilers do support overloading of functions which do not have external linkage, it is not supported by C14 nor am I aware (unfortunately) of any active efforts to add such a feature to future C standards.

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

Nonetheless, GCC can be made, using macros, to support a form of overloading which is not supported directly in languages with operator overloading. GCC includes an intrinsic which will identify whether an expression can be evaluated as a compile-time constant. Using this intrinsic, one can write a macro which can evaluate an expression different ways (including by calling functions) depending upon the argument. This can be useful in some cases where a formula would evaluate as a compile-time constant if given a compile-time constant argument, but would yield a horrible mess if given a variable argument. As a simple example, suppose one wishes to bit-reverse a 32-bit value. If the value is constant, one could do that via:

尽管如此,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)) )

And an expression like uint32_t x=word_swap(0x12345678);would simply load xwith 0x87654321. On the other hand, if the value is not a constant, the result would be horrible: an expression like uint32_t y=word_swap(x);might generate many dozens of instructions; a call to a function with a partially-unrolled loop would be almost as fast but a lot more compact. On the other hand, using a loop would prevent the result from being regarded as a compile-time constant.

而像uint32_t x=word_swap(0x12345678);这样的表达式只会加载x0x87654321。另一方面,如果该值不是常量,结果将是可怕的:像这样的表达式uint32_t y=word_swap(x);可能会生成几十条指令;调用具有部分展开循环的函数几乎同样快,但更紧凑。另一方面,使用循环会阻止结果被视为编译时常量。

Using GCC, one can define a macro which will either use the constant-yielding macro if given a constant, or call a function when given a variable:

使用 GCC,你可以定义一个宏,如果给定一个常量,它要么使用常量产生宏,要么在给定变量时调用一个函数:

#define wswap(x) \
  (__builtin_constant_p((x)) ? word_swap((x)) : word_swap_func((x))

This approach can't do everything type-based overloading can do, but it can do many things overloading can't.

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

回答by Karthik Balaguru

C Does not support overloading. But we can implement that functionality by programming our own library that in turn could provide overloading support.

C 不支持重载。但是我们可以通过编写我们自己的库来实现该功能,而该库又可以提供重载支持。

回答by chinmaya

No c does not support function overloading. But you can get it to compile/work if you are using g++ (a c++ compiler).

没有 c 不支持函数重载。但是,如果您使用 g++(c++ 编译器),则可以编译/工作。