In this section:
This error is generated when there is a mismatch in format specification, such as when a call to one of the printf
or scanf
routines contains a mismatch between a parameter type and the corresponding format specifier or the format string is nonsensical. Insure++ distinguishes several types of mismatches which have different levels of severity as follows:
|
Error messages are classified according to this scheme and can be selectively enabled or disabled
An example of format type mismatch occurs when the format specifiers passed to one of the printf routines do not correspond to the data, as shown below.
/* * File: badform1.c */ main() { double f = 1.23; int i = 99; printf("%d %f\n”, f, i); } |
This type of mismatch is detected during compilation. Another problem includes badform4.c
. A diagnosis similar to the one that follows applies.
[badform1.c:9] **BAD_FORMAT(incompatible)** Wrong type passed to printf (argument 2). Expected int, found double. >> printf("%d %f\n", f, i); [badform1.c:9] **BAD_FORMAT(incompatible)** Wrong type passed to printf (argument 3). Expected double, found int. >> printf("%d %f\n", f, i); |
A more dangerous problem occurs when the types passed as arguments to one of the scanf
functions are incorrect. In the following code, for example, the call to scanf
tries to read a double precision value, indicated by the %lf
format, into a single precision value. This will overwrite memory.
/* * File: badform2.c */ main() { int a; float f; scanf("%lf, %f); } |
This problem, as well as the WRITE_OVERFLOW (not shown), is diagnosed at compile time.
[badform2.c:9] **BAD_FORMAT(incompatible)** Wrong type passed to scanf (argument 2). Expected double *, found float *. >> scanf("%lf\n", &f); |
A third type of problem is caused when the format string being used is a variable rather than an explicit string. The following code contains an error handler that attempts to print out a message containing a filename and line number. In line 18 of the calling routine, however, the arguments are reversed.
/* * File: badform3.c */ char *file; int line; error(format) char *format; { printf(format,file,line); } main() { file = "foo.c"; line = 3; error("Line %d, file %s\n"); } |
[badform3.c:10] **BAD_FORMAT(incompatible)** >> printf(format,file,line); Format string is inconsistent: Wrong type passed to printf (argument 3). Expected pointer, found int. Format string: "Line %d, file %s\n" Stack trace where the error occurred: error() badform3.c, 10 main() badform3.c, 18 |
The error diagnosed in this message is in the incompatible category, because any attempt to print a string by passing an integer variable will result in garbage. With some compilers, this program may cause a core dump because of this error, while others will merely produce incorrect output.
There is, however, a second potential error in this code in the same line. Because the arguments are in the wrong order in line 7, an attempt will be made to print a pointer variable as an integer. This error is in the compatible class because a pointer and an integer are both the same size in memory. Because compatible BAD_FORMAT
errors are suppressed by default, you will not see it. These errors are suppressed because they tend to cause unexpected rather than incorrect behavior. If you enabled these errors, you would see a second problem report from this code.
If you run Insure++ on an architecture where pointers and integers are not the same length, then this second error would also be in the incompatible class and would be displayed by default.
Most of these problems are simple to correct based on the information given. Normally, the correction is one or more of the following
Change the format specifier used in the format string.
Change the type of the variable involved.
Add a suitable typecast.
You can correct Problem 1, for example, by simply changing the incorrect line of code as follows:
badform1.c, line 9: printf("%d %f\n", i, f);
The other problems can be similarly corrected.
If your application generates error messages that you wish to ignore, you can suppress BAD_FORMAT in the Suppressions Control Panel.
This directive suppresses all BAD_FORMAT messages. If you wish to be more selective and suppress only a certain type of error, you can use the following syntax where the arguments are one or more of the identifiers for the various categories of errors described in Overview:
BAD_FORMAT(class1, class2, …)
The problem with the pointer and integer that was not shown in the current example could be displayed by unsuppressing BAD_FORMAT(compatible)
. For an example of this option, as well as the remaining subcategories of BAD_FORMAT, see the example badform4.c.