Chapter 14 review. Are the following statements true or false? Explain why or why not.

a) Like Knobby's World instructions, C++ functions facilitate top-down decomposition.
True. By defining either instructions or functions, one can break a problem down into smaller and smaller parts down to the level of the primitive instructions or operations built into the language.

b) To transfer of control from a caller to a callee, the callee function must explicitly keep track of the state in the caller to which the program will return when it is done.
False, at least at the level of C++ code. The compiler generates the machine code necessary to keep track of state, but C++ source code need not do so.

c) A variable only exists while it is "in scope."
True. It gets created (and possibly initialized) when the running program enters the block in which it is defined and gets destroyed when the running program exits that block. It is "in scope" while the running program is executing that block.

d) The scope of a global (extern) variable is the file in which it is defined.
True. A global variable gets created before entering the main() function and destroyed after the main() function ends and is accessible by any code within that file. It's also possible to make it accessible in other files, by declaring it. For example, consider a variable declaration:

        float foo; //is thus defined in one .cc or .cpp file.

To get access to this variable from another file:

        extern float foo; //thus declared in another .cc or .cpp file

The linker will make sure that declaration are bounds to definitions compiled elsewhere.

e) C++ functions, like mathematical functions, always return a value.
True. A function with a void return type returns nothing.

f) A boolean function can only return one of two possible values.
True. A function with a bool return type can only return either true or false.

g) Functions can return objects (defined by classes).
True. For example:

       Lstring foo() { Lstring s; return s; } //returns an Lstring object

h) It's possible (and useful) to compile and run programs which contain stub functions.
True. Though a stub function has an empty body or just an output statement, a C++ compiler can still generate code and the resulting program will show that you've got the overall structure and flow of the program right.

i) Top-down testing is useful for testing individual functions.

False. Bottom-up testing is more oriented toward individual functions, top-down to integrating functions in whole programs. Of course, the two approaches can work together.

j) Side effects can make a program hard to understand and maintain.
True. Local changes to global variables are hard to see from outside the function. To understand the program's data, a programmer will need to track how they get modified in and out of many different functions. In the long run, it would be much better to isolate these variables more locally.

k) The actual parameter is what the callee function declares and manipulates.
False. The callee sees the formal parameter. The caller passes in the actual parameter.

l) A C++ compiler performs type checking, i.e., makes sure actual and formal parameters have identical types.
True. For example, if a formal parameter were float x and a caller attempted to passing in an Lstring, the C++ compiler would complain, since the actual and formal parameters aren't compatible: the compiler cannot find a way to convert an Lstring into an int.

m) A C++ compiler automatically arranges for parameter type promotion and demotion, if necessary.
True. It will automatically convert, say, an actual parameter of type int to a formal parameter of type float. Demotion is rarer, but most compiler will automatically convert a float actual parameter into an int, by truncating the remainder. A compiler may emit a warning about the effect of truncation.

n) It's possible that a constructor may be called while entering or returning from a function.
True. For example, if a program passes a C string actual parameter into an Lstring formal, the compiler will automatically arrange for the invocation of an Lstring constructor that takes a C string parameter.

o) Pass by value is more efficient than pass by reference.
False. Generally, for larger objects, pass by reference is more efficient, since it just passes an alias or address rather than a complete copy of the object. The difference is negligible for fundamental types such as int or float.

p) Pass by value helps promote more maintainable code than pass by reference.
True. Since pass by value copies the actual parameter, changes to the formal parameter do not affect the actual. Hence, no side effects.

q) Pass by const reference offers both efficiency and security, if used consistently.
True. It offers the efficiency of pass by reference, by not copying large objects. It also offers security, by guaranteeing that the formal parameter will not be altered, thus ruling out local side effects.

r) It's a good idea to use parameters to make functions more general.
True. Thus we generalized the computation of change for any denomination of coinage:

         int numCoins(int change,int unit,int & remainder)

s) It's possible to call the same function with different numbers of parameters.
True. But only if the function has been defined with default parameter values. For example: void foo(int x=1,int y=2) {} can be called with either two parameters, foo(3,4), one parameter, foo(5), or none, foo().

t) A function prototype must end with a semi-colon.
True. The semi-colon takes to place of a function body. Thus the compiler knows that it's looking at a prototype or declaration rather than a definition.

u) Test driver functions facilitate top-down decomposition for constructing programs.
False. Test driver functions facilitate bottom-up composition by making sure individual functions work as specified.

v) A test description should concentrate on confirming expecting behavior for core values.
False. A test description should also make sure a function works for boundary cases, such as the beginning and end of loops, or preconditions and postconditions.

w) Preconditions for a functions are usually constraints on input parameters.
True. Preconditions typically require that an input parameter be within a narrower range of values, for example than an int parameter be positive.

x) Satisfying postconditions is the responsibility of the client or caller of a function.
False. That's the responsibility of the supplier or implementation of the function itself. The caller is responsible for meeting the preconditions.

y) Including assert() macros in a program can ensure the correctness of a program.
True. An assert() macro that produces a false (zero) value at run-time will cause the program to stop and generate an error message.

z) This function is illegal, dangerous and pernicious:

        int foo() { return foo(); }

False or true, depending on your perspective. It's a perfectly legal recursive function, from the point of view of a C++ compiler. However, this particular function will recursively call foo() an indefinite number of times, because it has no bare or bottom-out case.