Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!cs.utexas.edu!rutgers!njin!princeton!notecnirp!nfs From: nfs@notecnirp.Princeton.EDU (Norbert Schlenker) Newsgroups: comp.os.minix Subject: Re: Zen and the Art of Library Programming Message-ID: <22702@princeton.Princeton.EDU> Date: 3 Jan 90 04:36:18 GMT References: <7259@nigel.udel.EDU> Sender: news@princeton.Princeton.EDU Reply-To: nfs@notecnirp.UUCP (Norbert Schlenker) Organization: Dept. of Computer Science, Princeton University Lines: 108 In article <7259@nigel.udel.EDU> Leisner.Henr@xerox.com (marty) writes: >Norbert Schlenker says: {{ > > >---------------------------------------------------------------------------- >#include >#include > >abort() >{ > while (1) > fprintf(stderr, "Stupid jerk!\n"); >} > >main() >{ > assert(0==1); >} > >---------------------------------------------------------------------------- > >This is a valid ANSI C program which should terminate with a SIGABRT >signal. >Instead, the linker will use the program's definition of abort(), and this >program will go into an infinite loop when run. (Just as an aside, this is >a useful test program for many compilers that claim ANSI compatibility.) >}} > >What is the compiler supposed to do with the program? Generate a warning? >Generate a fatal error? Its valid C code. Why should the compiler (for >the language) know anything about the library functions (this ain't PL/1). The compiler should compile the program without error or warning, because the program has no errors in it. The point is that the assert() macro has a guaranteed effect (according to ANSI), and the last part of that effect is to terminate the program by calling the abort() function. The abort() function cited by ANSI is that of the ANSI standard, not a programmer supplied one (i.e. ANSI expects the program to die after assert(0==1)). A C compiler/library/linker combination that can't do this is BROKEN. >I quickly glanced through the May, 88 dpans and found nothing to confirm or >deny it. Anyone have a reference? From the Dec'88 draft: Section 4.2.1.1 - The assert macro ... When it is executed, if expression is false, the assert macro writes information about the particular call that failed ... It then calls the abort function. ... Forward references: the abort function (4.10.4.1). >While having no proof one way or another, I maintain redefining library >functions is within the spirit of C. But that was before ANSI. > I often do it since the library >version doesn't do what I want or has problems or whatever. Recompiling >the source code with magic macros to use different functions (i.e. cc >-Dabort=myabort) is insufficient -- what if I want to library functions to >use my version ? But that was before ANSI. >A common mistake by beginning C programmers is to use library functions >names for their own functions and then watch the chaos that follows (read >and write are good examples, especially when the program does STDIO) . This is a common mistake, and the chaos is real. This is a side effect of the Unix philosophy best summarized as "Manual! What manual? This is Unix, son, you just gotta know!" (cribbed from a Usenet signature). It sure is fun to watch someone make this mistake - it's no fun to do it. >Part of the spirit of C I enjoy so much is the assumption the programmer >knows what he's doing (maybe he wants to redefine write() -- i.e. perhaps >do some special profiling and then generate the syscall). Ah, but you are guilty of reminiscing now. That's the spirit of K&R - C is just a high level assembler and if you want to do something, you can do it. But ANSI C is a different language - it was defined partly to guarantee that even schmucks could write programs that work. If you want to redefine write(), it's easy to do in Minix since you have the source code. It's easy to do in most Unix systems today, since they aren't ANSI aware. It will even be easy to do in the ANSIfied world. But it won't be easy to make an ANSI fwrite() use your rewritten write() then. And that's as it should be. Consider, for example, the code for a remarkable new program that dials random bank computers and has them send you money. It is obvious that everyone should have this program. You NEED this program. It is written in C for a WHIZZBANG Model 67C/X and works fine there. It uses . It also has an internal routine named write(), which is just fine since a German wrote the WHIZZBANG's operating system, and the system call underlying fwrite() isn't write() but schreib() instead. Write(), regrettably, dials the FBI and informs them of the scam. Now don't you wish you had an ANSI conforming library? >One more note: >Does the Minix compiling system properly understand public/private? I >understood at one time static really didn't do anything regarding >name-space pollution. Not as far as I know. This is a sore point with me (and I assume many others). Eventually, there has got to be another ACK compiler that fixes this very significant defect. >marty Norbert