From owner-freebsd-hackers Fri Feb 5 18:05:34 1999 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id SAA10396 for freebsd-hackers-outgoing; Fri, 5 Feb 1999 18:05:34 -0800 (PST) (envelope-from owner-freebsd-hackers@FreeBSD.ORG) Received: from smtp02.primenet.com (smtp02.primenet.com [206.165.6.132]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id SAA10391 for ; Fri, 5 Feb 1999 18:05:31 -0800 (PST) (envelope-from tlambert@usr02.primenet.com) Received: (from daemon@localhost) by smtp02.primenet.com (8.8.8/8.8.8) id TAA20578; Fri, 5 Feb 1999 19:02:21 -0700 (MST) Received: from usr02.primenet.com(206.165.6.202) via SMTP by smtp02.primenet.com, id smtpd020472; Fri Feb 5 19:02:19 1999 Received: (from tlambert@localhost) by usr02.primenet.com (8.8.5/8.8.5) id TAA25935; Fri, 5 Feb 1999 19:01:56 -0700 (MST) From: Terry Lambert Message-Id: <199902060201.TAA25935@usr02.primenet.com> Subject: Re: C headers To: Matthew.Alton@anheuser-busch.com (Alton, Matthew) Date: Sat, 6 Feb 1999 02:01:55 +0000 (GMT) Cc: Hackers@FreeBSD.ORG In-Reply-To: <31B3F0BF1C40D11192A700805FD48BF90177670F@STLABCEXG011> from "Alton, Matthew" at Feb 5, 99 06:39:36 pm X-Mailer: ELM [version 2.4 PL25] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG > Why does printf() non need #include like the man page says? > A student asked me why and I can't explain this inconsistency. If you can explain symbol decoration in C++ objects, you can explain why ANSI C requires prototypes in scope, not necessarily for compilation and linking to succeed, but for proper function. Header files are only needed if you require a prototype in scope to deal with type promotion issues. In general, the only C code that needs prototypes in scope is code where the type promotion is not to type "int". For most general purpose computer architectures (e.g., ones which implement function arguments with promotion to int and passing on the stack), this is not a problem. For functions that accept/return types larger than "int" (i.e., where "int" would represent a demotion in size), you will run into problems. Such functions include any of the functions or system calls that take an off_t argument (for example: lseek). You will also run into problems with functions that take structure pointers or return them (example: stat), since the structure will not be defined without the header files. You can see similar promotion related problems that ANSI failed to address in the printf(3) function call. Specifically, examine the output of: #include main() { long long q_num = -3; long l_num = -3; int i_num = -3; short s_num = -3; char c_num = -3; printf( "a signed quad -3 is: %qx\n", q_num); printf( "a signed long -3 is: %lx\n", l_num); printf( "a signed int -3 is: %x\n", i_num); printf( "a signed short -3 is: %hx\n", s_num); printf( "a signed char -3 is: %x\n", c_num); } The type promotion results in a sign extension error. Probably the proper connection would be to provide a "b" (for "byte") modifier to the "x" and "X" types, e.g.: printf( "a signed char -3 is: %bx\n", num); But using prototypes is actually a kludge around the fact that the declaration and usage information is not stored in the symbol definition for the function in the object file format, since if it were, failure to abide by calling conventions could be caught at link time, and would not have required complicating the language (there are arguments that "C++ will replace C, so making the code compilable with C++, which *demands* prototypes, is good"; people who don't buy into C++ replacing C don't buy this argument). Like "decorated" symbols in C++ works around the lack of class attribution and overloading information in the object format, so prototypes in scope in C files are meant to work around the lack of argument and return type information for C functions. So the fact that you will potentially get undetectable errors if you compile without a prototype in scope can really be blamed on lazy compiler writers who didn't want to update their linker technology at the same time that they were adding assumptions to their compiler. Anyway, use the header files, and use the warning flags (they should probably default "on", but I'll bet the compiler won't compile if you do that 8-)). Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message