How to Implement function overloading in C

Source: Internet
Author: User

We all know that C ++ and other object-oriented languages support function overloading. C ++ relies heavily on the Mangling (damage, damage) of function names by the compiler ), that is, after the source code of C ++ is compiled, the name of the overloaded function with the same name will be damaged. Generally, a specific string is added before and after the original function name to distinguish different overloaded functions, then select the appropriate function based on different parameters during the call. The following code illustrates how the compiler handles normal function overloading: # include <iostream> usingnamespacestd; intfunc (void) {cout <"func without parameters" <endl;} intfunc (intia) {cout <"func with one int parameter:" <endl; cout <ia <endl;} intfunc (intia, floatfb) {cout <"func with one int pa Rameter and one float parameter "<endl; cout <ia <endl; cout <fb <endl ;}intmain () {func (); func (5 ); func (5, 5.0);} g ++-S. /t. the compilation code generated after cc compilation may be as follows :. file "t. cc ". local _ ZStL8 _ ioinit. comm _ ZStL8 _ ioinit, 1, 1. section. rodata. LC0 :. string "func without parameters ". text. globl _ Z4funcv. type _ Z4funcv, @ function _ Z4funcv :. LFB966 :. cfi_startproc pushl % ebp. cfi_def_cfa_offset8. cfi_offset5,-8 movl % Esp, % ebp. cfi_def_cfa_register5 subl $24, % esp movl $. LC0, 4 (% esp) movl $ _ ZSt4cout, (% esp) 1_movl $ _ KERNEL _, 4 (% esp) movl % eax, (% esp) call_ZNSolsEPFRSoS_E leave. cfi_restore5. cfi_def_cfa4, 4 ret. cfi_endproc. LFE966 :. size _ Z4funcv ,. -_ Z4funcv. section. rodata. LC1 :. string "func with one in T parameter ". text. globl _ Z4funci. type _ Z4funci, @ function _ Z4funci :. LFB967 :. cfi_startproc pushl % ebp. cfi_def_cfa_offset8. cfi_offset5,-8 movl % esp, % ebp. cfi_def_cfa_register5 subl $24, % esp movl $. LC1, 4 (% esp) movl $ _ ZSt4cout, (% esp) 1_movl8 (% ebp), % edx movl % edx, 4 (% esp) movl % eax, (% esp) call_ZNSolsEi movl $ _ ZSt4endlIcSt11char_trait SIcEERSt13basic_ostreamIT_T0_ES6 _, 4 (% esp) movl % eax, (% esp) call_ZNSolsEPFRSoS_E leave. cfi_restore5. cfi_def_cfa4, 4 ret. cfi_endproc. LFE967 :. size _ Z4funci ,. -_ Z4funci. section. rodata. align4. LC2 :. string "func with one int parameter and one float parameter ". text. globl _ Z4funcif. type _ Z4funcif, @ function _ Z4funcif :. LFB968 :. cfi_startproc pushl % ebp. cfi_def_cfa_offset8. cfi_offset5,-8 movl % Esp, % ebp. cfi_def_cfa_register5 subl $24, % esp movl $. LC2, 4 (% esp) movl $ _ ZSt4cout, (% esp) 1_movl $ _ KERNEL _, 4 (% esp) movl % eax, (% esp) call_ZNSolsEPFRSoS_E movl8 (% ebp), % eax movl % eax, 4 (% esp) movl $ _ ZSt4cout, (% esp) call_ZNSolsEi movl $ _ done S6 _, 4 (% esp) movl % eax, (% esp) call_ZNSolsEPFRSoS_E movl12 (% ebp), % eax movl % eax, 4 (% esp) movl $ _ ZSt4cout, (% esp) call_ZNSolsEf movl $ _ callback _, 4 (% esp) movl % eax, (% esp) call_ZNSolsEPFRSoS_E leave. cfi_restore5. cfi_def_cfa4, 4 ret. cfi_endproc. LFE968 :. size _ Z4funcif ,. -_ Z4funcif. globl main. type main, @ function main :. LFB969 :. cfi_startproc pushl % Ebp. cfi_def_cfa_offset8. cfi_offset5,-8 movl % esp, % ebp. cfi_def_cfa_register5 andl $-16, % esp subl $16, % esp call_Z4funcv movl $5 (% esp) call_Z4funci movl $0x40a00000, % eax movl % eax, 4 (% esp) movl $5, (% esp) call_Z4funcif movl $0, % eax leave. cfi_restore5. cfi_def_cfa4, 4 ret. cfi_endproc, we can see that the names of the three versions of overload functions in func are damaged after compilation. The Compiler renames them as _ Z4funcv, _ Z4funci, _ Z4funcif, (the g ++ compiler may add a feature related to the parameter type to the function name based on the function parameter type. Fixed the suffix. For example, func (void) is changed to _ Z4funcv, func (int) is changed to _ Z4funci, and func (int, float) is changed to _ Z4funcif ), then, when calling func () of each version, the compiler selects an appropriate overload function based on different parameter types. For example, calling func () actually calls _ Z4funcv and calls func (5, 5.0) actually called _ Z4funcif and so on. However, in many cases, variable parameters can be used to implement function overloading in the C language. The open function defined in the POSIX interface is a very good example. # include <sys/types. h> # include <sys/stat. h> # include <fcntl. h> intopen (constchar * pathname, intflags); intopen (constchar * pathname, intflags, mode_t mode); the third parameter of the second open function indicates the permission to create a file, so this is the example of implementing function overloading in C:-) So how can we implement function overloading in C? A common practice is to use the variable parameter va_args: # include <stdarg. h> voidva_start (va_list ap, last); type va_arg (va_list ap, type); voidva _ End (va_list ap); voidva_copy (va_list dest, va_list src); The following is a simple example. "Two functions are overloaded. The first one is two parameters, the second function contains three functions. The third function is optional and # include <stdio. h> # include <stdarg. h> voidva_overload2 (intp1, intp2) {printf ("va_overload2% d \ n", p1, p2);} voidva_overload3 (intp1, intp2, intp3) {printf ("va_overload3% d \ n", p1, p2, p3);} staticvoidva_overload (intp1, intp2 ,...) {if (p2 = 3) {va_list v; va_start (v, p2); intp 3 = va_arg (v, int); va_end (v); va_overload3 (p1, p2, p3); return;} va_overload2 (p1, p2 );} you can call it as follows: # include <stdio. h> intmain () {va_overload (); va_overload (, 3); return0;} In addition to overloading based on the number of parameters, you can also overload the parameter type (typeof ), this mainly utilizes the built-in functions of GCC, __builtin_types_compatible_p () and _ builtin_choose_expr (), such as structs1 {inta; intb; doublec ;}; structs2 {longlonga; longlongb;}; voidgcc_overload_s1 (structs1 s) {Printf ("Got a struct s1: % d % f \ n", s. a, s. b, s. c);} voidgcc_overload_s2 (structs2 s) {printf ("Got a struct s2: % lld \ n", s. a, s. b);} // warning: dereferencing type-punned pointer will break strict-aliasing rules # definegcc_overload (A) \__ builtin_choose_expr (_ partition (typeof (), structs1), \ gcc_overload_s1 (* (structs1 *) & A), \ _ builtin_choose_expr (_ builtin_types_compatib Le_p (typeof (A), structs2), \ gcc_overload_s2 (* (structs2 *) & A), (void) 0) or A more advanced Syntax: voidgcc_type_overload_aux (inttypeval ,...) {switch (typeval) {case1: {va_list v; va_start (v, typeval); structs1 s = va_arg (v, structs1); va_end (v); gcc_overload_s1 (s ); break;} case2: {va_list v; va_start (v, typeval); structs2 s = va_arg (v, structs2); va_end (v); gcc_overload_s2 (s); break ;} default: {printf ("Invalid Type to 'gcc _ type_overload () '\ n "); exit (1) ;}}# definegcc_type_overload (A) \ gcc_type_overload_aux (\__ builtin_types_compatible_p (typeof (), structs1) * 1 \ + _ builtin_types_compatible_p (typeof (A), structs2) * 2 \, A) the other two methods for implementing function overloading using C can be macro and preprocessing, and function pointers, but the specific overload method should also be determined according to the specific application scenario. However, implementing function overloading in C requires developers to write a lot of extra code by themselves, which is a little higher. This makes C language not suitable for compiling standard application interfaces in function overloading mode. Therefore, if someone asks you whether C can implement function overloading, you cannot say "C does not support function overloading." The answer should be: "depending on the situation, depending on the mood of the Application Scenario:-)".

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.