You're absolutely right that it's unusual for a compiler to warn about specific functions.
Warnings about printf
(and scanf
, and related) format specifiers are quite unusual -- but then, these functions are quite unusual in the first place.
As other answers have explained, it's at least possible for a compiler to "know" about certain functions and to perform special, extra, compile-time checks like this -- and given that printf
and scanf
and friends are simultaneously very unusual and very popular, it's quite appropriate for compilers to be doing this extra checking, unusual though it is.
Once upon a time (I'm talking about the pre-ANSI, K&R days here), C programmers knew they had to be careful about calling functions with the correct number and type of arguments. (In those days, the only way to automatically check that was to use lint
, which some programmers did but many programmers didn't.) And if you were used to being careful, it was easy to be careful about printf
and friends, also.
Today, though, it's a different story. ANSI C function prototypes have been in use for a generation. Most programmers today implicitly expect a compiler to automatically convert the types of function arguments, and to complain about incompatible mismatches. (As an example of the way things have changed: in the old days, calling sqrt(144)
was an error that quietly gave mysterious results, but today it's fine.)
So today, I have a great deal of sympathy for programmers who are learning C, and are baffled by printf
. If you're completely used to the protections afforded to you by function prototypes, it's a pretty great mystery why
int i = 3;
float f = 4.5;
printf("i as a float is %f, f as an int is %d\n", i, f);
doesn't work. Unlike the old days, I suspect, it is very hard to remember that, when you call printf
(but pretty much only when you call printf
), it's your job to get all the types right, because the compiler won't insert any implicit conversions.
The bottom line is that, today, not only is it possible for a compiler to warn about mismatches in calls to printf
and the like, I believe it's pretty much a moral imperative. When we introduced function prototypes, we promised programmers type safety for function arguments, so it's really not fair to quietly withdraw that promise when it comes to printf
.
[P.S. Yes, of course I know why function prototypes can't promise complete type safety for varargs functions like printf
. But that's got nothing to do with my argument here. Also, yeah, I know, life isn't fair, so call me an old softie with my highfalutin talk of "moral imperatives". :-) ]