Q. Is it possible to execute code even after the program exits the main() function?
The standard C library provides a function named atexit() that can be used to perform "cleanup" operations when your program terminates. You can set up a set of functions you want to perform automatically when your program exits by passing function pointers to the atexit() function. Here's an example of a program that uses theatexit() function:
#include <stdio.h>
#include <stdlib.h>
void close_files(void);
void print_registration_message(void);
int main(int, char**);
int main(int argc, char** argv)
{
...
atexit(print_registration_message);
atexit(close_files);
while (rec_count < max_records)
{
process_one_record();
}
exit(0);
}
This example program uses the atexit() function to signify that the close_files() function and theprint_registration_message() function need to be called automatically when the program exits. When themain() function ends, these two functions will be called to close the files and print the registration message. There are two things that should be noted regarding the atexit() function. First, the functions you specify to execute at program termination must be declared as void functions that take no parameters. Second, the functions you designate with the atexit() function are stacked in the order in which they are called with atexit(), and therefore they are executed in a last-in, first-out (LIFO) method. Keep this information in mind when using theatexit() function. In the preceding example, the atexit() function is stacked as shown here:
atexit(print_registration_message);
atexit(close_files);
Because the LIFO method is used, the close_files() function will be called first, and then theprint_registration_message() function will be called.
The atexit() function can come in handy when you want to ensure that certain functions (such as closing your program's data files) are performed before your program terminates.
Q. What does a function declared as PASCAL do differently?
A C function declared as PASCAL uses a different calling convention than a "regular" C function. Normally, C function parameters are passed right to left; with the PASCAL calling convention, the parameters are passed left to right.
Consider the following function, which is declared normally in a C program:
int regular_func(int, char*, long);
Using the standard C calling convention, the parameters are pushed on the stack from right to left. This means that when the regular_func() function is called in C, the stack will contain the following parameters:
long
char*
int
The function calling regular_func() is responsible for restoring the stack when regular_func() returns.
When the PASCAL calling convention is being used, the parameters are pushed on the stack from left to right.
Consider the following function, which is declared as using the PASCAL calling convention:
int PASCAL pascal_func(int, char*, long);
When the function pascal_func() is called in C, the stack will contain the following parameters:
int
char*
long
The function being called is responsible for restoring the stack pointer. Why does this matter? Is there any benefit to using PASCAL functions?
Functions that use the PASCAL calling convention are more efficient than regular C functions—the function calls tend to be slightly faster. Microsoft Windows is an example of an operating environment that uses the PASCAL calling convention. The Windows SDK (Software Development Kit) contains hundreds of functions declared as PASCAL.
When Windows was first designed and written in the late 1980s, using the PASCAL modifier tended to make a noticeable difference in program execution speed. In today's world of fast machinery, the PASCAL modifier is much less of a catalyst when it comes to the speed of your programs. In fact, Microsoft has abandoned the PASCAL calling convention style for the Windows NT operating system.
In your world of programming, if milliseconds make a big difference in your programs, you might want to use the PASCAL modifier when declaring your functions. Most of the time, however, the difference in speed is hardly noticeable, and you would do just fine to use C's regular calling convention.
Comments
Post a Comment