C++ Primer - Chapter 6 (Functions) Flashcards

1
Q

What does a function definition consist of?

A

A return type specifier, an identifier, a parameter list and a function body.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

How is a function executed?

A

By using the call operator, ().

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is the term for the values supplied to the call operator?

A

Arguments.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What purpose do function arguments have?

A

To initialise the function parameters.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q
What is the purpose of the following function?
int f(int val)
{
int ret = 1; 
while (val > 1) ret *= val--; 
return ret; 
}
A

To compute the factorial of val.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

True or false? A function call causes the called function to be suspended and the execution of the calling function to begin.

A

False. Execution of the calling function is suspended and execution of the called function begins.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How can an empty parameter list be written implicitly and explicitly?

A

Implicitly:
void f1() { /* . . . / }
Explicitly:
void f2(void){ /
. . . */ }

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q
Where is the error in the following code?
int f3(int v1, v2) { /* . . . */ } 
int f4(int v1, int v2) { /* . . . */ }
A
int f3(int v1, v2) { /* . . . */ } 
// This is an error; there is no type specifier for v2.
int f4(int v1, int v2) { /* . . . */ }
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What keyword typically indicates the end of a function?

A

The “return” keyword.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is the difference between a parameter and an argument?

A

A parameter is a value defined through the function prototype and an argument is a value passed through a function call.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q
Indicate which of the following functions are in error and why. 
(a) int f() {
string s;
// . . .
return s;
}
(b) f2(int i) { /* . . . */ }
(c) int calc(int v1, int v1) { /* . . . */ }
(d) double square(double x) return x * x;
A
(a) int f() {
string s;
. . .
return s;
}
// Error; returns a string not an int.
(b) f2(int i) { /* . . . */ }
// Error; no return type.
(c) int calc(int v1, int v1) {/* . . . */ }
// Error; parameters have the same name.
(d) double square(double x) return x * x;
// Error; no braces around function body.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What is the lifetime of an object?

A

The time during the programs’s execution that the object exists.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What is an “automatic object”?

A

An object that exists only while a block is executing.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

True or false? Parameters are not automatic objects.

A

False.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What value does an uninitialised variable of built-in type defined inside a function body take?

A

The value is undefined.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

How can a local variable be created inside a function and be forced to persist across function calls?

A

By using the “static” keyword.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

When is a local static object destroyed?

A

When the program terminates.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

How is a local static object with no explicit initialiser initialised?

A

By value initialisation. Local static variables of built-in type will be initialised to zero.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Where can parameter names be omitted?

A

In function declarations or in a function definition when the corresponding parameter is unused.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

What is another name for a function declaration?

A

A function prototype.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Is it an error to only declare a function?

A

No, not if the function is never used.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

True or false? Parameter initialisation works in the same way that variable initialisation works.

A

True.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

What is the term given to an argument when the corresponding parameter is a reference?

A

“Passed by reference.”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

When is an argument “passed by value”?

A

When the argument value is copied in the initialisation of a function parameter.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

Programmers accustomed to C often use pointer parameters to access objects outside a function body. Is this also true for C++?

A

No. C++ programmers tend to use reference parameters.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

Can a low-level const be passed to a nonconst reference parameter?

A

No.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

Name three common ways to manage pointer (to array) parameters.

A
  1. Using a marker to specify the extent of an array (e.g. the null character ‘\0’ in a string).
  2. Using the STL convention; passing a pointer to the first and one past the last element in the array.
  3. Explicitly passing a size parameter.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
28
Q

How can a function be declared such that it can take an unknown number of arguments if the parameters are all of the same type? What if the arguments differ?

A

Using an initialiser_list if the parameters are all of the same type and a variadic template if the parameter types differ.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
29
Q

True or false? The elements of an initialiser_list can be changed after initialisation.

A

False. They are always const values.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
30
Q

How must a list of values be passed to an initialiser_list parameter?

A

By list initialisation, e.g.

error_msg({“functionX”,”okay”});

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
31
Q

When should ellipsis parameters only be used?

A

When interfacing C++ code to C code that uses a C library facility called varargs.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
32
Q

What is the only thing that a function with void return type can return?

A

The result of a function that also has void return type.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
33
Q

Is it a good idea to return a reference or pointer to a local object? Why?

A

No, because the local object will be deleted once it goes out of scope and access to the variable outside the function scope will be undefined.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
34
Q

Can the result of a function be returned using list initialisation?

A

Yes, in C++11, a braced list of values can be returned to list initialise the return value.

If the braced list is empty, the result will be value initialised.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
35
Q

Can a function return the value of a built-in type using list initialisation?

A

Yes, but the braced list may only contain one argument, and the returned value must not lead to a narrowing conversion.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
36
Q

When is it valid to return a reference? A reference to const?

A

When the variable is defined outside the function body, e.g. you return the value of an argument passed by reference.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
37
Q
Indicate whether the following function is legal. If so, explain what it does; if not, correct any errors and then explain it.
int &get(int *arry, int index) 
{ 
return arry[index]; 
}
int main() 
{
int ia[10];
for (int i = 0; i != 10; ++i)
get(ia, i) = i;
}
A

The code:

int &get(int *arry, int index) 
{ 
return arry[index]; 
}
int main() 
{
int ia[10];
for (int i = 0; i != 10; ++i)
get(ia, i) = i;
}

is legal; it loops over the entries of an array and assigns the i-th entry the value i. This makes use of the fact that the return value of get(…) is a reference.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
38
Q

Is there a problem with the following code to compute the factorial of a function? If so, why?

int factorial(int val)
{
if (val != 0) return factorial(val-1) * val;
return 1;
}
A

If the argument to val is less than zero, this function will continue forever, otherwise it is fine.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
39
Q

In the call to factorial (below), why did we pass val-1 rather than val–?

int factorial(int val)
{
if (val != 0) return factorial(val-1) * val;
return 1;
}
A

We passed val-1 rather than val– in the code below because the postfix operator would pass the unchanged value of val to factorial before decrementing val. The function would then descend into a recursion loop.

int factorial(int val)
{
if (val != 0) return factorial(val-1) * val;
return 1;
}
40
Q

What might a function prototype for a function that returns a pointer to an array look like?

A

int (f(int i))[10];
Or, more generally:
Type (
function(parameter list))[dimension].

41
Q

What are two clear ways to declare a function that returns a pointer to an array?

A
1. Using a type alias, e.g.
typedef int arrayT[10];
arrayT* func(int i);
2. Using a trailing return type (C++11), e.g.
auto func(int i) -> int(*)[10];
42
Q

What is the term given to a function that has the same name but a different parameter list?

A

A “function overload”.

43
Q

Can a function be overloaded with a different return type alone?

A

No.

44
Q

True or false? A function with a top-level const parameter is indistinguishable from one with a nonconst parameter.

A

True.

45
Q

Suppose a function has two overloads: one has a nonconst parameter and the other has a low-level const. If a nonconst variable is passed to the function, which overload will be used?

A

The one that does not require a const type conversion of the argument at run-time, i.e. the nonconst version will be used.

46
Q

When is a const_cast particularly useful? Why?

A

In function overloading, to forward arguments to versions of the same function whose parameters have different constness. This avoids code duplication of the function body.

47
Q

Why must a const_cast be used to upcast the nonconst arguments to const arguments in the following code?

const string &shorterString(const string &s1, const string &s2)
{
return s1.size() <= s2.size() ? s1 : s2;
}
string &amp;shorterString(string &amp;s1, string &amp;s2)
{
auto &amp;r = shorterString(const_cast(s1),const_cast(s2));
return const_cast(r);
}
A

If the variables passed to the same function were not cast to low-level consts, there would be a recursion loop of function calls; the original function would just forward the function call to itself over and over again.

const string &amp;shorterString(const string &amp;s1, const string &amp;s2)
{
return s1.size() <= s2.size() ? s1 : s2;
}
string &amp;shorterString(string &amp;s1, string &amp;s2)
{
auto &amp;r = shorterString(const_cast(s1),const_cast(s2));
return const_cast(r);
}
48
Q

What is the term given to the process by which a particular function call is associated with a specific function from a set of overloaded functions?

A

Function matching.

49
Q

What three outcomes are there for function matching?

A
  1. A “best match” is found that is better than all others.
  2. No match is found for the given call.
  3. There is more than one match; this called an “ambiguous match”.
50
Q

Is the following code legal?

string read();
void print(const string &amp;);
void print(double); 
void fooBar(int ival)
{
bool read = false; 
string s = read(); 
void print(int); 
print("Value: "); 
print(ival); 
print(3.14); 
}
A
string read();
void print(const string &amp;);
void print(double); 
void fooBar(int ival)
{
bool read = false; 
// Variable bool is defined in a new scope; hides the outer declaration of read.
string s = read(); 
// This is an error; read is a bool variable, not a function.
void print(int); 
// The function print is now defined in a new scope, hiding previous instances of print.
print("Value: "); 
// This is an error; print(const string &amp;) is hidden.
print(ival); 
// This is okay; print(int) is visible.
print(3.14); 
// This is okay; calls print(int) as print(double) is hidden.
}
51
Q

True or false? If the declaration of a function is found in an inner scope, the compiler will still search for previous usages of the name in an outer scope.

A

False; all usages of the name in outer scope will be ignored.

52
Q

Where must “default arguments” be placed in a parameter list?

A

After all other parameters that don’t have default arguments.

53
Q

How many times can a function be declared? How many times can default arguments to the function be declared?

A

Several times, however, default arguments can only be declared once per argument.

54
Q

Can a default argument be declared before its trailing arguments are?

A

No. It may only be declared after its trailing arguments have been declared.

55
Q

Which, if either, of the following declarations are errors? Why?

(a) int ff(int a, int b = 0, int c = 0);
(b) char *init(int ht = 24, int wd, char bckgrnd);

A
(a) int ff(int a, int b = 0, int c = 0);
// This is okay; default arguments are placed at the end.
(b) char *init(int ht = 24, int wd, char bckgrnd);
// This is an error; the default argument should be placed at the end.
56
Q

Which, if any, of the following calls are illegal? Why? Which, if any, are legal but unlikely to match the programmer’s intent? Why?
char init(int ht, int wd = 80, char bckgrnd = ’ ’);
(a) init();
(b) init(24,10);
(c) init(14, ’
’);

A

char init(int ht, int wd = 80, char bckgrnd = ’ ’);
(a) init();
// This is an error; at least one argument must be provided.
(b) init(24,10);
// This is valid; ht=24 and wd=10.
(c) init(14, ’
’);
// This is legal (as a char can be cast to an int) but it is likely not what the programmer intended.

57
Q

How can a function be expanded “in line” at each call?

A

By using the “inline” keyword.

58
Q

Where must the “inline” keyword be placed?

A

Before the function’s return type.

59
Q

How can a function be used to initialise a constexpr variable?

A

By making it a constexpr function.

60
Q

What conditions must a constexpr function satisfy?

A

The return type and the type of each parameter must be a literal type, and there must only be one return statement in the function definition.

61
Q

True or false? constexpr functions are implicitly inline.

A

True, as a compiler will try to replace a call to a constexpr function with its resulting value.

62
Q

True or false? A constexpr function must return a constant expression.

A

False, a constexpr function is not required to return a constant expression.

63
Q

How many times can inline and constexpr functions be defined?

A

Several times, however, every definition must be identical.

64
Q

Name two preprocessor macros that can be used for debugging a C++ program.

A

The “assert” and “NDEBUG” macros, which are part of the “cassert” header.

65
Q

What is wrong with the following code?

std::assert(1+2==3);

A

“assert” is a preprocessor macro managed by the preprocessor and not the compiler, so the std:: prefix should not be used.

66
Q

How can NDEBUG be used to disable the evaluation of assert?

A

By defining NDEBUG, i.e. by using: “#define NDEBUG”.

67
Q

Name five useful preprocessor macros other than assert and NDEBUG.

A

__func__, __file__, __line__, __date__ and __time__.

68
Q

What is a “candidate function”?

A

A function, found during function matching, that has the same name as the called function and has been declared before the point of call.

69
Q

What is a “viable function”?

A

A viable function (in function matching) has the same number of parameters as there are arguments in the call and the type of each argument must match, or at least be convertible to, the type of the corresponding parameter.

70
Q

What is the outcome of function matching if a nonzero set of viable functions can be found but no best match?

A

It is rendered an “ambiguous call”.

71
Q

True or false? During function matching, arithmetic conversion from a char to an int is deemed “better” than a char to a double.

A

False, all arithmetic conversions are treated as equivalent to each other.

72
Q
Explain the effect of the second declaration in each one of the following sets of declarations. Indicate which, if any, are illegal.
(a) int calc(int&amp;, int&amp;);
int calc(const int&amp;, const int&amp;);
(b) int calc(char*, char*);
int calc(const char*, const char*);
(c) int calc(char*, char*);
int calc(char* const, char* const);
A
(a) int calc(int&amp;, int&amp;);
int calc(const int&amp;, const int&amp;);
// The second declaration is distinct from the first and allows const arguments to be passed.
(b) int calc(char*, char*);
int calc(const char*, const char*);
// The second declaration is distinct from the first and allows const arguments to be passed.
(c) int calc(char*, char*);
int calc(char* const, char* const);
// Top-level consts are ignored during copy initialisation so the functions are indistinguishable to the compiler and the second "hides" the first declaration.
73
Q

What is the difference between the following two declarations?
bool pf(const string &, const string &);
bool (
pf)(const string &, const string &);

A
bool *pf(const string &amp;, const string &amp;);
// Function declaration where the return type is a pointer to a boolean.
bool (*pf)(const string &amp;, const string &amp;);
// Declaration of a function pointer.
74
Q
What type does the following function have? How is a pointer to that function written?
bool lengthCompare(const string &amp;, const string &amp;);
A
bool lengthCompare(const string &amp;, const string &amp;);
// This function has type "bool(const string &amp;, const string &amp;)". Thus, a pointer to lengthCompare can be written as:
bool (*pf)(const string &amp;, const string &amp;);
// (Note the parentheses.)
75
Q

Suppose pf is a function pointer. What is the difference between the following two function calls, if any?
bool b1 = pf(“hello”, “goodbye”);
bool b2 = (*pf)(“hello”, “goodbye”);

A

The calls below are equivalent, because when we use a function name as a value, it is automatically converted to a pointer.
bool b1 = pf(“hello”, “goodbye”);
bool b2 = (*pf)(“hello”, “goodbye”);

76
Q

Given a function lengthCompare and a compatible function pointer fp, in what two ways can lengthCompare be assigned to fp?

A

lengthCompare can be assigned to fp as:
fp=lengthCompare;
fp=&lengthCompare;
The former holds because a function used as a value is automatically converted to a pointer.

77
Q

What does the following function return?

int (f1(int))(int, int);

A
int (*f1(int))(int*, int);
// Reading this declaration from the inside out: f1 has a parameter list, so f1 is a function. f1 is preceded by a * so f1 returns a pointer. The type of that pointer itself has a parameter list, so the pointer points to a function. That function returns an int.
78
Q
Describe the differences between the following declarations.
typedef bool* Func(const string&amp;, const string&amp;);
typedef bool(*FuncP)(const string&amp;, const string&amp;);
A
typedef bool* Func(const string&amp;, const string&amp;);
typedef bool(*FuncP)(const string&amp;, const string&amp;);
// The former declaration returns a pointer while the latter declaration is a pointer to a function type.
79
Q
Describe the differences between the following declarations, where lengthCompare is the name of a function.
typedef decltype(lengthCompare) Func2; 
typedef decltype(lengthCompare) *FuncP2;
A
typedef decltype(lengthCompare) Func2; 
typedef decltype(lengthCompare) *FuncP2;
// decltype returns a function type and not a pointer to function type so a pointer must be added separately when required (e.g. declaration of a function pointer variable).
80
Q

How can the following function be rewritten using a trailing return?
int (f1(int))(int, int);

A
int (*f1(int))(int*, int);
can be rewritten as
auto f1(int) -> int (*)(int*,int);
81
Q

What is an “ambiguous call”?

A

Compile-time error that results during function matching when two or more functions provide an equally good match for a call.

82
Q

What are “arguments”?

A

Values supplied in a function call that are used to initialise the function’s parameters.

83
Q

What are “parameters”?

A

Local variables declared inside the function parameter list.

Parameters are initialised by the arguments provided in each function call.

84
Q

What are “automatic objects”?

A

Objects that exist only during the execution of a block.

85
Q

What is a “best match” function?

A

A function selected from a set of overloaded functions for a call.

If a best match exists, the selected function is a better match than all the other viable functions for at least one argument in the call and is no worse on the rest of the arguments.

86
Q

What is a “function prototype”?

A

Function declaration, consisting of the name, return type, and parameter types of a function.

87
Q

What are “candidate functions”?

A

Set of functions that are considered when resolving a function call.

Candidate functions have the same name as the called function and have been declared before the point of call of the function.

88
Q

What are “viable functions”?

A

A subset of the candidate functions. To be viable, a function must have the same number of parameters as there are arguments in the call, and the type of each argument must match—or be convertible to—the type of its corresponding parameter.

89
Q

What is a “function”?

A

A callable unit of computation.

90
Q

What is an “inline function”?

A

The “inline” keyword provides a request to the compiler to expand a function at the point of call, if possible.

Inline functions avoid the normal function-calling overhead.

91
Q

What are “local static objects”?

A

Local objects whose value persists across calls to the function.

92
Q

What is “object code”?

A

The format into which the compiler transforms our source code.

93
Q

What is “function matching”?

A

Compiler process by which a call to an overloaded function is resolved.

94
Q

What is an “overloaded function”?

A

A function that has the same name as at least one other function.

Overloaded functions must differ in the number or type of their parameters.

95
Q

What is the call operator?

A

The () operator; it executes a function.

96
Q

According to the C++17 standard, what is the output of this program?

template void f(T &i) { std::cout &laquo_space;1; }
template <> void f(const int &i) { std::cout &laquo_space;2; }

int main() {
  int i = 42;
  f(i);
}
A

The answer is 1.

For the call f(i), since the type of i is int, template argument deduction deduces T = int.

The explicit specialization template <> void f(const int &i) has T = const int, which is not the same type as int, so it doesn’t match.

Instead, template void f(T &i) with T = int is used to create the implicit instantiation void f(int&).