Concepts / Calling Functions and Passing Arguments

Calling Functions and Passing Arguments

C++ programs get their work done mainly by calling functions.

  • Programming

Why Programs Are Built From Called Functions

C++ programs get their work done mainly by calling functions. Most C++ programs are not one long list of instructions. Instead, the work is split into named pieces, and the program gets things done by calling those pieces at the right moments. Each piece is a function.

Keep that picture in mind as you read. A program is a set of named pieces that call one another. The rest of this article follows a single call from start to finish, so you can see exactly where the program goes and how it comes back.

What do you think happens?

main() reaches a line that calls add(2, 3). Before reading on, what do you think happens next?

  • The program ends, because the call is the last thing main() does

  • Execution jumps into add(), runs its body, and then returns to the line after the call

  • The line after the call runs first, and add() runs later at the end of the program

Reveal answer
Answer:

Execution jumps into add(), runs its body, and then returns to the line after the call.

A call transfers control to the function, the function does its operation, and control comes back to the place the call was made. The rest of this article explains the rules that make this work in C++.

Tracing One Call From main

Follow the path a single call takes. The calling code, here main(), pauses at the call. The function body performs its operation. A value then travels back to the place the call was made, where it can be used. The example below is written for this article to show that path in real code.

cpp
Output
5
Notes on the code
  • Line 3 is a declaration: it makes add known before main uses it
  • Line 6 is the call: control moves into add with 2 and 3 supplied
  • Line 6 finishes only after add hands back 5, which is stored in total
  • Lines 11 to 13 are the definition: they specify how add does its operation
main()calling codeadd()function body1. call add(2, 3)2. return 5
When main() calls add(2, 3), where does execution jump, and how does it return to the line after the call?

Read the trace in order. Execution reaches the call on the line that assigns total. It moves into add. The body computes a + b. Then the result comes back to the line where the call was made, and the assignment finishes. Execution then continues with the line after that, which prints the value.

2first argumenta, bparameters of adda + boperation in the body5returned valuetotalcaller's variable3second argumentfills afills bused byreturnedstored in
How do the values 2 and 3 move from the call into the parameters, and how does the returned value move back to the caller?

Declaring Versus Defining a Function

A function cannot be called unless it has been previously declared. The declaration comes earlier in the program than the call. This is a rule the compiler relies on: when the code says to call a function, the function must already be known to the program. Declaring a function introduces its name and the shape it has, so that code written earlier can refer to it correctly.

Defining a function is a different job. A definition specifies how the function's operation is to be done. It contains the body, the block of statements that does the work. So the two ideas separate cleanly: a declaration makes the function known, and a definition says what the function actually does.

Prototype lineint add(int a, int b);Makes add knownname and shapeFunction definitionint add(int a, int b) { ...}Specifies theoperationbody with return a + b;givesgives
What is the difference between a declaration and a definition, and which one contains the function body?

A useful way to keep these apart is to think of a declaration as an entry in a list of available tools, and the definition as the instructions for how each tool works. The list lets other code refer to the tool by name. The instructions are where the operation is actually specified. In the program above, line 3 is the list entry and lines 11 to 13 are the instructions.

Reading the Return Type in a Signature

Every function has a return type, and that type tells you whether the function gives a value back to the code that called it. The return type is the part of the function's shape that answers this question before you ever look inside the body. Reading it first lets you predict what the caller can do with the result of the call.

intreturn type: a value oftype int comes backaddfunction name used at thecall(int a, int b)parameter list: values thecaller supplies
In the line int add(int a, int b), which part is the return type, which is the name, and what does each part tell the caller?

Read the signature from left to right. The first word is the return type, which tells you what kind of value, if any, the caller receives. The next word is the name the caller uses. The parentheses hold the parameter list, which describes the values the caller passes in when it makes the call. In the example, the call add(2, 3) supplies 2 and 3, which fill a and b.

Void Versus Value-Returning Functions

The question to ask of any function is simple: does its return type say void, or does it name a kind of value? If it says void, the caller receives nothing back from the call. If it names a value type, the function is designed to give a value back, and the caller can use that value.

FeatureReturn type voidReturn type names a value (for example int)
Does the caller receive a value?No, nothing comes backYes, a value of that type comes back
Can the caller use the result?No result to useYes, it can be stored or used in an expression
What the signature tells youThe call is for its effect onlyThe call produces a value of the named type
Example from this articleA function that only printsint add(int a, int b)

Reading the return type tells you what the caller can do with the call.

The return type is the first clue you have about a function, so check it before reading the body. A caller that expects a value depends on the return type being a value type. The return type is the part of the signature that sets that expectation.

Common Mistakes With Declarations and Return Types

  • Common mistake

    Calling a function before it has been declared

    What it looks like
    int main() { int t = add(2, 3); return t; } appears above any declaration of add
    Why it fails

    A function cannot be called unless it has been previously declared, and the compiler relies on this order.

    Do this instead

    Place the declaration, or the definition, of add before the line that calls it.

  • Common mistake

    Treating the declaration as if it contains the body

    What it looks like

    Writing only int add(int a, int b); and expecting the call to produce a sum

    Why it fails

    A declaration makes the name and shape known. The definition is where the operation is specified.

    Do this instead

    Provide a definition with a body that performs the operation.

  • Common mistake

    Letting the declaration and definition disagree

    What it looks like

    Declaring int add(int a, int b); but defining it with a different return type or different parameters

    Why it fails

    The declaration describes the shape the rest of the code relies on, so the definition must match that shape.

    Do this instead

    Copy the signature exactly from the declaration into the definition.

  • Common mistake

    Assuming a function returns a value because it has a name that sounds like a result

    What it looks like

    Calling a function named printTotal and expecting its result to be stored

    Why it fails

    Only the return type says whether a value comes back. A void return type means the caller receives nothing.

    Do this instead

    Read the return type first. If it says void, do not try to use a value from the call.

Practice Reading Signatures

EASY

Given the signature void report(int score);, can a caller write int x = report(90); and use the result? Explain using the return type. Then say what the caller receives from the call.

Hints
  • Look at the first word of the signature, which is the return type.
  • The source says a return type of void means the function does not return a value.
MEDIUM

A program calls int square(int n) before any declaration or definition of square appears in the file. Describe what is wrong, then write the declaration that fixes it and identify its return type and parameter list.

Hints
  • Recall that a call requires an earlier declaration.
  • A declaration needs the same name, return type, and parameter list as the definition.

Key Takeaways

  • C++ programs get their work done mainly by calling functions, which are named pieces that the program invokes at the right moments.
  • A function must be declared before it is called. A declaration introduces its name and shape, while a definition specifies how the operation is done.
  • The return type shows whether a function hands a value back. A void return type means the caller receives nothing, while a value type means the caller can use the result.
  • Most errors with functions come from calls before declarations, mismatched signatures, and misreading what the return type promises.

Related concepts

More concepts starting with C