Functions Flashcards
Chapter 6 (20 cards)
What will be the argument order of evaluation for
fact( 10*10, 20+20, 30/20)
There are no guarantees about evaluation oder of parameters
When is a local static object in a function initialized and when is it destroyed
It is initialized when first time execution passes through the object’s definition and is destroyed when program terminates
Can we redefine void fcn(const int i){} as void fcn(int){}
No, as top level const-ness is ignored in a parameter
int i = 42; const int *cp = &i; // 1 const int &r = i; // 2 const int &r2 = 42; // 3 int *p = cp; // 4 int &r3 = r; // 5 int &r4 = 42; // 6
- OK, cp cant change value of i
- OK, r can’t change value of i
- OK, const reference can hold literal values
- ERROR, can’t ignore top const
- ERROR, can’t ignore top level const
- ERROR, non-const reference can hold literals values
void reset (int &i);
int i = 0;
const int ci = i;
std::string::size_type ctr = 0;
reset(&i); // 1 reset(&ci); // 2 reset(i); // 3 reset(ci); // 4 reset(42); // 5 reset(ctr); // 6
- calls the version of reset that has an int* parameter
- error: can’t initialize an int* from a pointer to a const int object
- calls the version of reset that has an int& parameter
- error: can’t bind a plain reference to the const object ci
- error: can’t bind a plain reference to a literal
- error: types don’t match; ctr has an unsigned type
What is the difference between the three void print(const int*); void print(const int[]); void print(const int[10]);
All declarations are equivalent: Each declares a function with a single parameter of type const int. When the compiler checks call to print, it checks only that the argument has type const int:
3 Common techniques to pass an array to a function
- Using a marker to specify extent an array ( eg null )
- Pass the range of first and last pointers ( printarr(begin(), end()); )
- Explicitly passing a size parameter ( printarr(arr, 10);)
How to delare a function which takes reference to an array as parameter
void print(int (&arr)[10]); () is mandatory as &arr[10] will declare array of references
How to delare a function which takes multi dimensional array as parameter
void print(int (*matrix)[10] With any array, a multidimensional array is passed as a pointer to its first element. Because we are dealing with an array of arrays, that element is an array, so the pointer is a pointer to an array. The size of the second (and any subsequent) dimension is part of the element type and must be specified. Parentheses around matrix is necessary
How to use initializer_list
void print(std::initializer_list li);
print ({1, 2, 3});
Why should we not return reference to a local object
// disaster: this function returns a reference to a local object
const string &manip()
{
string ret;
// transform ret in some way
if (!ret.empty())
return ret; // WRONG: returning a reference to a local object!
else
return “Empty”; // WRONG: “Empty” is a local temporary string
}
Both of these return statements return an undefined value—what happens if we try to use the value returned from manip is undefined. In the first return, it should be
obvious that the function returns a reference to a local object. In the second case, the string literal is converted to a local temporary string object. That object, like the
string named s, is local to manip. The storage in which the temp
What is the associativity of function call operator
Its left assiciative
hence following is possible
auto lenght = std::string(“hello”).size();
How to return pointer to an array
1. typedef/ type aliasing tyepdef int arr[10]; using arr = int[10]; arr* func(int i); 2. using the form Type (*function(parameter_list))[dimension] int (*func(int))[10]; 3. Trailing return type auto func(int) -> int(*)[]; 4. using decltype int odd = {1, 2, 3, 4}; decltype (odd) *func(int);
Can we overload function differing on reference const-ness
Yes, int lookup(int &i); int lookup(const int &i);
Similarly following can be overloaded int lookup(int *i); int lookup(const int *i);
Does a local function definition ( or declaration ) hide other function declarations?
Yes,
void print(double); void print(std::string); void foo() { void print(); print(3.14); // ERROR, this is hidden print("Hello"); // ERROR, this is also hidden print();// OK, this is available }
What is a constexpr function
A constexpr function is a function that can be used in a constant expression. A constexpr function is defined like any other function but must meet certain
restrictions:
1. The return type and the type of each parameter in a must be a literal type
2. The function body must contain exactly one return statement
- constexpr function are implicitly inline
- A constexpr function is permitted to return a value that is not a constant:
// scale(arg) is a constant expression if arg is a constant expression
constexpr size_t scale(size_t cnt) { return new_sz() * cnt; }
What are the argument type conversion rules when compiler calls its parameters
Conversions are ranked as follows:
1. An exact match. An exact match happens when:
• The argument and parameter types are identical.
• The argument is converted from an array or function type to the corresponding pointer type.
• A top-level const is added to or discarded from the argument.
2. Match through a const conversion
3. Match through a promotion
4. Match through an arithmetic or pointer conversion.
5. Match through a class-type conversion.
Which manip function is called
void manip(long); void manip(float); manip(3.14);
The literal 3.14 is a double. That type can be converted to either long or float.
Because there are two possible arithmetic conversions, the call is ambiguous.
How to declare a pointer to a function, assign it later, call it and pass it as a parameter
/// Original function bool lengthCompare(const string &, const string &);
bool (*pf)(const string &, const string &); // uninitialized
// assign it later pf = lengthCompare; // pf now points to the function named lengthCompare pf = &lengthCompare; // equivalent assignment: address-of operator is optional
// calling it bool b1 = pf("hello", "goodbye"); // calls lengthCompare bool b2 = (*pf)("hello", "goodbye"); // equivalent call bool b3 = lengthCompare("hello", "goodbye"); // equivalent call
// passing it a function arguement // third parameter is a function type and is automatically treated as a pointer to function void useBigger(const string &s1, const string &s2, bool pf(const string &, const string &)); // equivalent declaration: explicitly define the parameter as a pointer to function void useBigger(const string &s1, const string &s2, bool (*pf)(const string &, const string &));
How do you return a pointer to a function?
1. Using alias using F = int(int*, int); // F is a function type, not a pointer using PF = int(*)(int*, int); // PF is a pointer type // using aliases PF f1(int); // ok: PF is a pointer to function; f1 returns a pointer to function F f1(int); // error: F is a function type; f1 can't return a function F *f1(int); // ok: explicitly specify that the return type is a pointer to function
- Using f1 directly
int (f1(int))(int, int);
2. Trailing type auto f1(int) -> int (*)(int*, int);