[C++] Functions

binh12A3
6 min readOct 27, 2021

pass by value, pass by reference, pass by address, extern keyword, prototype,…

Overview

How many ways to call a function ?

There are 3 ways to call a function

1. Pass by value

Advantages:

  • Arguments cam be const (i.e : 1, 2), variable (i.e : x), formular (i.e : x + 1), struct, class, enumerator.
  • The value of the argument will be copied to a parameter, so everything happens in the func() will not affect to the argument (the value of argument is unchanged).

Disadvantage

  • Consumes more memory, since it has to copy the value from arguments to parameters.
  • Decrease performance in case the arguments are complex like structs, classes especially when that func is called many times. Since in every calls, it has to clone/copy values.
  • It can only return 1 value by return command.

When we use pass by value ?

  • When arguments are simple datatypes.
  • When we don’t want to change the value of arguments after calling func

When we shouldn’t use pass by value ?

  • When arguments are arrays, structs, classes

Demo

2. Pass by reference

What is reference ?

  • Reference is a “special” variable, it acts like a nickname of other variable.
  • We can define a reference by using “&” symbol. i.e : int &x
  • Every changes on reference will affect to variable and vice-versa. (i.e : 1 location of memory has 2 ways to call)

Advantages:

  • Function can changed the value of arguments. If you don’t want this, you can use const reference.
  • Don’t waste time and memory to clone/copy values of arguments.
  • It can return multiple values.

Disadvantage

  • Arguments must be a variables (which have addresses), can’t be constants, expressions (which do not have address.). We can walkaround it by using const reference.
  • It’ll hard to determine which parameters are input, output. We can walkaround it by using naming convention (i.e : sumOUT) or using const reference.

When we use pass by reference ?

  • When arguments are complex types like structs, classes
  • When we want to change the value of argument after calling func.

When we shouldn’t use pass by reference ?

  • When argument are simple datatypes.

Demo

When we should use pass by const reference ?

  • If you want to improve performance of the func, but you don’t want arguments are changed.
  • It helps us to determine quickly that argument can’t be changed in the function.
  • In “pass by reference” you can not pass a constant (i.e : 1,2,3) or an expression (i.e : x + 2) since it doesn’t have any address. If you still want to use pass by reference for such that cases or you don’t want to change the value of arguments then use could use const reference.

Demo

3. Pass by address/pointer

  • We should use pass by pointer when argument is an array.
  • passy by ref is saftier than pass by pointer, so pass by ref is recommended.
  • We should check NULL before using pointer parameter in function.
  • Pass by pointer is normally used to pass an array.
  • When we pass a pointer as a function’s parameter, then the pointed value will be copied to pointer parameter. Which mean if you change value of pointer parameter, you just change value of the cloned one. Therefore the original pointer won’t be changed.

Function returns value, reference, address

1. Return value

  • Used to return basic datatypes or return the local variable which is defined in the function or return the parameter which is passed by value.
  • It’ll reduce the performance if the returned value is struct, class,…

2. Return address

  • Faster than return value, because it just need to copy the address then return to the caller.
  • It can’t return the address of the local variable which is defined in the function or constant or expression.
  • Used to return the dynamically allocated memory or the parameter which is passed by address, or when we want to return an array or pointer.

3. Return ref

  • It works like passing ref to function (i.e : we pass a ref and we return a ref)
  • It can’t return the address of the local variable which is defined in the function or constant or expression.
  • Used to return the argument which is passed by reference, or return an element from an array, return a struct or complex class which won’t be destroyed when exit the function.

Why we need Declaration (prototype) ?

  • The compiler will compile from top to bottom, so if we put sub-functions below main() then it’ll throw a compile error “identifier not found”.
  • So that’s why we should declare functions on top of the file. Declaration helps compiler know about the existance of fucntions. And the compiler won’t allocate memory lcoation because it’s just a declaration.
  • Declaration not only helps us prevent the compile error, but also helps us know quickly functions esist in this file.
  • We can declare multiple times, but can define only 1 time.

What is the “extern” keyword ?

The “extern” keyword indicates that this object is defined in other place which means compiler doesn’t need to allocate memory for this object.

  • With a declaration of variable, we must have “extern” keyword
  • With a declaration of function, “extern” keyword is optional and can be ommited. And no “extern” allowed for type declaration.

Inline functions

  • When a function is called, CPU will store the address of the current line of code which is being executed to determine the place to come back after calling a function. Then copy the arguments of the function into stack. Then finally, redirect to the called function. CPU now will execute the code in the function, store the returned value in a memory location (RAM). Then return the control to the location where the function was called.
  • When we call a function, it’ll take a period of time to look up the address, clone values,…So if we call many functions, it’ll take much many time…
  • “inline” keyword suggests (not force) the compiler to execute inline expansion to improve the performance.
  • The compiler won’t execute inline expansion when : function contains loop, function contains static variable, recursive function, function contains switch or goto,…
  • Almost modern compiler will implicitly execute inline expansion which means we don’t need an explicit inline keyword.
  • We can add inline keyword in header file.
  • Inline function will save the cost of calling function, the cost of variables in stack when a function is called. (increase the speed)
  • The disadvantage is it’ll increase the size of execuation file because of duplicated code.

Functions overloading

  • We can overload functions if they have the different returned datatype, or different number of or datatype of parameters.
  • We can’t overload functions if they are only different in the returned datatype, or parameter is a typedef because typedef is just an alias, not a class.
  • We can’t overload functions if one has parameter is a pointer, and the other has parameter is an array. Because pointer and array are the same.
  • We can overload functions with const parameter only when this parameter is a ref or pointer.

Default arguments

  • Default parameters must be the last parameters of the function and must be located as a sequence.
  • Default parameters can be declared in the forward declaration (prototype) or in the definition, but not both places at the same time.
  • We can’t use default parameter to overload a function

--

--