Coupon Accepted Successfully!


Question 11

What are inline functions?

Before reading the answer, please be aware that inline functions are non-standard C. They are provided as compiler extensions. But, nevertheless, one should know what they are used for.

The inline comment is a request to the compiler to copy the code into the object at every place the function is called. That is, the function is expanded at each point of call. Most of the advantage of inline functions comes from avoiding the overhead of calling an actual function. Such overhead includes saving registers, setting up stack frames, and so on. But with large functions the overhead becomes less important. Inlining tends to blow up the size of code, because the function is expanded at each point of call.

int myfunc(int a)

inline int myfunc(int a)

Inlined functions are not the fastest, but they are the kind of better than macros (which people use normally to write small functions).

#define myfunc(a)   \
{ \
   ...                          \

The problem with macros is that the code is literally copied into the location it was called from. So if the user passes a "double" instead of an "int" then problems could occur. However, if this senerio happens with an inline function the compiler will complain about incompatible types. This will save you debugging time stage.

Good time to use inline functions is

1. There is a time criticle function.
2. That is called often.
3. Its small. Remember that inline functions take more space than normal functions. 

Some typical reasons why inlining is sometimes not done are:

1. The function calls itself, that is, is recursive.
2. The function contains loops such as for(;;) or while().
3. The function size is too large.

Question 12

How to declare an array of N pointers to functions returning pointers to functions returning pointers to characters?

Declare it this way

char *(*(*a[N])())(); 

Even this seems to be correct


Question 13

Can we declare a function that can return a pointer to a function of the same type?

We cannot do it directly. Either have the function return a generic function pointer, with casts to adjust the types as the pointers are passed around; or have it return a structure containing only a pointer to a function returning that structure.

Question 14

How can I write a function that takes a variable number of arguments? What are the limitations with this? What is vprintf()?

The header stdarg.h provides this functionality. All functions like printf(), scanf() etc use this functionality.

The program below uses a var_arg type of function to count the overall length of strings passed to the function.


int myfunction(char *first_argument,...)
   int length;
   va_list argp;
   va_start(argp, first);
   char *p;

   length = strlen(first_argument);
   while((p = va_arg(argp, char *)) != NULL)
     length = length + strlen(p);


int main()
  int length;
  length = myfunction("Hello","Hi","Hey!",(char *)NULL);

How can I find how many arguments a function was passed?

Any function which takes a variable number of arguments must be able to determine from the arguments themselves, how many of them there have been passed. printf() and some similar functions achieve this by looking for the format string. This is also why these functions fail badly if the format string does not match the argument list. Another common technique, applicable when the arguments are all of the same type, is to use a sentinel value (often 0, -1, or an appropriately-cast null pointer) at the end of the list. Also, one can pass an explicit count of the number of variable arguments. Some older compilers did provided a nargs() function, but it was never portable.

Is this allowed?

int f(...)

No! Standard C requires at least one fixed argument, in part so that you can hand it to va_start().

So how do I get floating point numbers passed as arguments?

Arguments of type float are always promoted to type double, and types char and short int are promoted to int. Therefore, it is never correct to invoke

va_arg(argp, float); 

instead you should always use

va_arg(argp, double)

Similarly, use

va_arg(argp, int)

to retrieve arguments which were originally char, short, or int.

How can I create a function which takes a variable number of arguments and passes them to some other function (which takes a variable number of arguments)?

You should provide a version of that other function which accepts a va_list type of pointer.

So how can I call a function with an argument list built up at run time?

There is no portable way to do this. Instead of an actual argument list, you might want to pass an array of generic (void *) pointers. The called function can then step through the array, much like main() steps through char *argv[].

What is the use of vprintf(), vfprintf() and vsprintf()?

Below, the myerror() function prints an error message, preceded by the string "error: " and terminated with a newline:

void myerror(char *fmt, ...)
  va_list argp;
  fprintf(stderr, "error: ");
  va_start(argp, fmt);
  vfprintf(stderr, fmt, argp);
  fprintf(stderr, "\n");

Question 15

With respect to function parameter passing, what is the difference between call-by-value and call-by-reference? Which method does C use?

In the case of call-by-reference, a pointer reference to a variable is passed into a function instead of the actual value. The function's operations will effect the variable in a global as well as local sense. Call-by-value (C's method of parameter passing), by contrast, passes a copy of the variable's value into the function. Any changes to the variable made by function have only a local effect and do not alter the state of the variable passed into the function.

Does C really have pass by reference?


C uses pass by value, but it can pretend doing pass by reference, by having functions that have pointer arguments and by using the & operator when calling the function. This way, the compiler will simulate this feature (like when you pass an array to a function, it actually passes a pointer instead). C does not have something like the formal pass by reference or C++ reference parameters.

How will you decide whether to use pass by reference, by pointer and by value?

The selection of the argument passing depends on the situation.

  • A function uses passed data without modifying it:

    • If the data object is small, such as a built-in data type or a small structure then pass it by value.
    • If the data object is an array, use a pointer because that is the only choice. Make the pointer a pointer to const.
    • If the data object is a good-sized structure, use a const pointer or a const reference to increase program efficiency. You save the time and space needed to copy a structure or a class design, make the pointer or reference const.
    • If the data object is a class object, use a const reference. The semantics of class design often require using a reference. The standard way to pass class object arguments is by reference.

  • A function modifies data in the calling function:

    • If the data object is a built-in data type, use a pointer. If you spot a code like fixit(&x), where x is an int, its clear that this function intends to modify x.
    • If the data object is an array, use the only choice, a pointer.
    • If the data object is a structure, use a reference or a pointer.
    • If the data object is a class object, use a reference.


Test Your Skills Now!
Take a Quiz now
Reviewer Name