BogoToBogo
  • Home
  • About
  • Big Data
  • Machine Learning
  • AngularJS
  • Python
  • C++
  • go
  • DevOps
  • Kubernetes
  • Algorithms
  • More...
    • Qt 5
    • Linux
    • FFmpeg
    • Matlab
    • Django 1.8
    • Ruby On Rails
    • HTML5 & CSS

Function Overloading

cplusplus_icon.png




Bookmark and Share





bogotobogo.com site search:




Which function does the compiler pick?

When we have multiple function definitions, we need to know which function will the compiler choose.


When the compiler picks the function, the return type is not considered, and only the signature matters. In other words, function name, number of parameters, and the types of each parameters will make the difference.

Here we have some candidates for a function call f('x');

  1. void f(int);
  2. float f(float, float = 911);
  3. void f(char);
  4. char *f(const char *);
  5. char f(const char &);
  6. template void f(const T&);
  7. template void f(T*);

Here are the factors that decides the rankings of the candidates:

  1. Of course, exact match.
    int exactly matches int &
    char & exactly matches const char &
  2. Regular functions win over template functions.
  3. Conversion via promotion:
    char/short -> int
    float -> double
  4. Conversion via standard conversion
    int -> char
    long -> double

Let's follow the step of the selection:

  1. #4 and #7 are out because an integral type cannot be converted to a pointer type.
  2. #1 is better than #2 because char to int promotion while char to float is a standard promotion.
  3. #3, #5, and #6 are better than #1 and #2 since they are exact matches.
  4. #3 and #5 win over #6 because #6 is a template.
  5. With #3 and #5, we will have ambiguity. We will get a complain from our compiler.

As another example, what will be called from the call int n = add(float(3.14))?

  1. int add(int n)
  2. long add(long n)
  3. double add(double n)

Answer is #3 because we have a case for promotion from float to double. So, it will call #3 and the result will be converted to int.



const Object - which function does the compiler pick?

Before we go over the effect of constness of parameter on the overloading, let's think about the overloading functions regarding the return type and signature of a function. As we already know return type is not recognized as a function signature. When we declare two functions whose return type and parameters match exactly, then our compiler think the second declaration is a redeclaration of the first. However, with different return types, it will be an declaration error of the second function if the parameters match exactly.

As shown in the code below, we need to know what const makes difference to the overloading functions, and also need to aware that there is additional constraint such as the parameter passed into the function.

The case (1) takes a non-const object while in the case (2) we have const object as a parameter. Between (3) and (4), we take an reference to an object.

Let's look at the following code:

struct A
{
	int m_i;
	char m_c[6];
};

void f(A){}          // (1)
void f(const A){}    // (2) Error in redeclaration
void f(A &){}        // (3)
void f(const A &){}  // (4)

int main()
{
    A objA = {100, "Hello"};

    f(objA);

    return 0;
}
  1. If we have only #3 and #4, #3 will be chosen because the call is from non-const type.
  2. However, between #1 and #2, we get an ambiguity complain from the compiler. That's because the preference between const and non-const only applies to reference or pointer type. The reason? It's simple. We copy the object whether it's a non-const or const. Compiler can't tell the difference. So, it complains.

Another minor thing we should know is:
we cannot overload based on whether the pointer itself const or not:

f(int *);
f(int *const) // redeclaration

That's because no matter what the pointer type (const or non-const) is, the object passed in will be copied. Compiler cannot tell the difference.



extern "C" scope - calling C function from C++

When we call C functions from C++, we need to use extern "C". This is because C++ allows function overloading while C does not. As a result, C++ function names are mangled to get additonal information in the symbol table such as the number and type of each function parameter. So, C code compiled by C compiler cannot be called by C++ code. As an example, the code below gives a link time error:

error LNK2019: unresolved external symbol "void __cdecl c_func(int)" (?c_func@@YAXH@Z) referenced in function _main

Here is the code:

// main.cpp
#include <iostream>
#include "CHeader.h"
#include "Header.h"

int main() {
	int n = 10;
	c_func(n);
	cpp_func(n);
	cpp_func(n,n);
	return 0;
}

// CHeader.h
void c_func(int);

// Header.h
#include <iostream>
void cpp_func(int);
void cpp_func(int,int);

// cpp_funcs.cpp
#include <iostream>
using namespace std;

void cpp_func(int a)
{
	cout << "cpp_func(int)" << endl;
}

void cpp_func(int a, int b)
{
	cout << "cpp_func(int, int)" << endl;
}

// c_func.c
#include <stdio.h>
void c_func(int a)
{
	printf("void c_func(int a)\n");
}

To fix the problem, we must wrap our C API in an extern "C" construct in C header file. This will force the C++ compiler use C-style call convention for the functions contained the extern scope. So, the CHeader.h should be modified as shown below:

// CHeader.h
#ifdef __cplusplus
extern "C" {
#endif

void c_func(int);

#ifdef __cplusplus
}
#endif

In summary, by wrapping extern "C" around C APIs, we make a C function-name called from C++ code to have 'C' linkage without any name mangling. The linkage block defined above, can be used to create a common C and C++ header.

Note:

  1. the __cplusplus directive will be automatically defined when we use C++ compiler.

    We can find discussions on the extern "C" from stackoverflow.

  2. The extern "C" directive specifies only the linkage convention not the scope and storage class of variables.


Lake





Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization

YouTubeMy YouTube channel

Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong






Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong






C++ Tutorials

C++ Home

Algorithms & Data Structures in C++ ...

Application (UI) - using Windows Forms (Visual Studio 2013/2012)

auto_ptr

Binary Tree Example Code

Blackjack with Qt

Boost - shared_ptr, weak_ptr, mpl, lambda, etc.

Boost.Asio (Socket Programming - Asynchronous TCP/IP)...

Classes and Structs

Constructor

C++11(C++0x): rvalue references, move constructor, and lambda, etc.

C++ API Testing

C++ Keywords - const, volatile, etc.

Debugging Crash & Memory Leak

Design Patterns in C++ ...

Dynamic Cast Operator

Eclipse CDT / JNI (Java Native Interface) / MinGW

Embedded Systems Programming I - Introduction

Embedded Systems Programming II - gcc ARM Toolchain and Simple Code on Ubuntu and Fedora

Embedded Systems Programming III - Eclipse CDT Plugin for gcc ARM Toolchain

Exceptions

Friend Functions and Friend Classes

fstream: input & output

Function Overloading

Functors (Function Objects) I - Introduction

Functors (Function Objects) II - Converting function to functor

Functors (Function Objects) - General



Git and GitHub Express...

GTest (Google Unit Test) with Visual Studio 2012

Inheritance & Virtual Inheritance (multiple inheritance)

Libraries - Static, Shared (Dynamic)

Linked List Basics

Linked List Examples

make & CMake

make (gnu)

Memory Allocation

Multi-Threaded Programming - Terminology - Semaphore, Mutex, Priority Inversion etc.

Multi-Threaded Programming II - Native Thread for Win32 (A)

Multi-Threaded Programming II - Native Thread for Win32 (B)

Multi-Threaded Programming II - Native Thread for Win32 (C)

Multi-Threaded Programming II - C++ Thread for Win32

Multi-Threaded Programming III - C/C++ Class Thread for Pthreads

MultiThreading/Parallel Programming - IPC

Multi-Threaded Programming with C++11 Part A (start, join(), detach(), and ownership)

Multi-Threaded Programming with C++11 Part B (Sharing Data - mutex, and race conditions, and deadlock)

Multithread Debugging

Object Returning

Object Slicing and Virtual Table

OpenCV with C++

Operator Overloading I

Operator Overloading II - self assignment

Pass by Value vs. Pass by Reference

Pointers

Pointers II - void pointers & arrays

Pointers III - pointer to function & multi-dimensional arrays

Preprocessor - Macro

Private Inheritance

Python & C++ with SIP

(Pseudo)-random numbers in C++

References for Built-in Types

Socket - Server & Client

Socket - Server & Client 2

Socket - Server & Client 3

Socket - Server & Client with Qt (Asynchronous / Multithreading / ThreadPool etc.)

Stack Unwinding

Standard Template Library (STL) I - Vector & List

Standard Template Library (STL) II - Maps

Standard Template Library (STL) II - unordered_map

Standard Template Library (STL) II - Sets

Standard Template Library (STL) III - Iterators

Standard Template Library (STL) IV - Algorithms

Standard Template Library (STL) V - Function Objects

Static Variables and Static Class Members

String

String II - sstream etc.

Taste of Assembly

Templates

Template Specialization

Template Specialization - Traits

Template Implementation & Compiler (.h or .cpp?)

The this Pointer

Type Cast Operators

Upcasting and Downcasting

Virtual Destructor & boost::shared_ptr

Virtual Functions



Programming Questions and Solutions ↓

Strings and Arrays

Linked List

Recursion

Bit Manipulation

Small Programs (string, memory functions etc.)

Math & Probability

Multithreading

140 Questions by Google



Qt 5 EXPRESS...

Win32 DLL ...

Articles On C++

What's new in C++11...

C++11 Threads EXPRESS...

Go Tutorial

OpenCV...








Contact

BogoToBogo
contactus@bogotobogo.com

Follow Bogotobogo

About Us

contactus@bogotobogo.com

YouTubeMy YouTube channel
Pacific Ave, San Francisco, CA 94115

Pacific Ave, San Francisco, CA 94115

Copyright © 2024, bogotobogo
Design: Web Master