dg@lakart.UUCP (David Goodenough) (08/11/89)
From article <15257@duke.cs.duke.edu>, by ndd@macbeth.cs.duke.edu (Ned D. Danieley): > Another problem is: > ... >>? #define ENDOFFILE -1 > ... >>? done=ENDOFFILE; > > some compilers will interpret this as the old =- assignment > operator. this is one place where style can really make a difference: > > done = ENDOFFILE; > > is easier to read and doesn't piss off cc. The correct solution is 1. Use <stdio.h>, and EOF, because there are no guarantees that EOF has to be -1: I could use -42 if the spirit so moved me. 2. #define ENDOFFILE (-1) with the original, it is left as an excercise to see why some compilers will barf on: a = x-ENDOFFILE; With parentheses, the problem is avoided completely, so style doesn't come into it. -- dg@lakart.UUCP - David Goodenough +---+ IHS | +-+-+ ....... !harvard!xait!lakart!dg +-+-+ | AKA: dg%lakart.uucp@xait.xerox.com +---+
scs@adam.pika.mit.edu (Steve Summit) (08/17/89)
In article <652@lakart.UUCP> dg@lakart.UUCP (David Goodenough) writes: >1. Use <stdio.h>, and EOF, because there are no guarantees that EOF has to be > -1: I could use -42 if the spirit so moved me. Is this true? Harbison and Steele (not necessarily a definitive pANS reference, I know) imply that it is always -1; at least, their discussion (p. 311 in the second edition) includes the example line #define EOF (-1) I agree that depending on the value is a bad idea, but it can be easy to write code which does so. One way is to start defining your own error codes which might be returned, along with EOF, from some intermediate-level input routines: #define ERROR (-2) A better way (which is portable as long as you know that all successful returns are positive) is #define ERROR (EOF-1) The only trouble here is that the header file in which you #define ERROR then ought to #include <stdio.h>, but that isn't necessarily a good idea under old implementations... Steve Summit scs@adam.pika.mit.edu
gwyn@smoke.BRL.MIL (Doug Gwyn) (08/17/89)
In article <13569@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >In article <652@lakart.UUCP> dg@lakart.UUCP (David Goodenough) writes: >>1. Use <stdio.h>, and EOF, because there are no guarantees that EOF has to be >> -1: I could use -42 if the spirit so moved me. >Is this true? Yes; EOF can be defined as any int value that differs from all possible char values. > #define ERROR (EOF-1) Don't do this. You don't know what EOF might be defined as, so this might not work right. EOF belongs to the C implementation. Invent your own symbols for your own uses.
maart@cs.vu.nl (Maarten Litmaath) (08/18/89)
gwyn@smoke.BRL.MIL (Doug Gwyn) writes: \In article <13569@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: \... \> #define ERROR (EOF-1) \ \Don't do this. You don't know what EOF might be defined as, so \this might not work right. What should he use instead? #define ERROR (-2) ... might not work either! -- kilogram, n.: the amount of cocaine |Maarten Litmaath @ VU Amsterdam: you can buy for $100K. |maart@cs.vu.nl, mcvax!botter!maart
gwyn@smoke.BRL.MIL (Doug Gwyn) (08/19/89)
In article <3019@solo1.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes: >What should he use instead? > #define ERROR (-2) >... might not work either! I already answered that: He should not attempt to add his own extensions onto the getc() extended range (characters + EOF), but should define his own special values. For example: int my_getch() { int c = getchar(); return c != EOF ? c : ferror(stdin) ? MY_ERR : MY_EOF; } where MY_ERR and MY_EOF are any two distinct negative ints.
mouse@mcgill-vision.UUCP (der Mouse) (08/28/89)
In article <10765@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn) writes: > In article <13569@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >> #define ERROR (EOF-1) > Don't do this. You don't know what EOF might be defined as, so this > might not work right. Then as far as I can see there is *no* way to (portably) choose an int value which is not EOF and not a valid char. Anything I can do, as far as I can see, will (for some choice of EOF, int range, and char range) either overflow, re-use the value of EOF, or re-use the value of some char. > EOF belongs to the C implementation. Invent your own symbols for > your own uses. Fine. But how? By the way, it seems to me that the required existence of EOF implies that it is not a legal implementation choice to make char and int identical. Is this true? (Flame retardant: I didn't say "sane", I said "legal".) der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
gwyn@smoke.BRL.MIL (Doug Gwyn) (08/28/89)
In article <1625@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes: >In article <10765@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn) writes: >> EOF belongs to the C implementation. Invent your own symbols for >> your own uses. >Fine. But how? #include <stdio.h> #define MY_EOF (-1234) /* presumably in some local header */ #define MY_ERR (-4321) int MyGetChar() { int c; return (c = getchar()) == EOF ? ferror(stdin) ? MY_ERR : MY_EOF : c; } >By the way, it seems to me that the required existence of EOF implies >that it is not a legal implementation choice to make char and int >identical. Is this true? Since in such an implementation an int would be unable to represent all possible values in the range of a unsigned char, as required by the specification for some library routines, it would not be standard conforming.
scs@hstbme.mit.edu (Steve Summit) (08/29/89)
In article <1625@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes: >In article <10765@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn) writes: >> In article <13569@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >>> #define ERROR (EOF-1) >> Don't do this. You don't know what EOF might be defined as, so this >> might not work right. >Then as far as I can see there is *no* way to (portably) choose an int >value which is not EOF and not a valid char. Anything I can do, as far >as I can see, will... either overflow, re-use the value of EOF, >or re-use the value of some char. Sure there is: #if EOF != -2 #define ERROR (-2) #else #define ERROR (-3) #endif The only reason I didn't do this in the program that prompted the original complaint was that I didn't want to require that <stdio.h> be #included before the header file that was trying to #define ERROR. (I can't yet depend on ANSI's guarantee that multiple #inclusions of standard header files are safe, so I didn't have the header file in question #include <stdio.h> itself. It occurs to me that #ifndef EOF #include <stdio.h> #endif is probably a safe way to protect against a non-idempotent <stdio.h>. I used to occasionally cheat and use #ifndef FILE for this purpose, but FILE isn't necessarily a preprocesser macro and should probably be a typedef instead. But EOF is required to be a macro, right?) Steve Summit
gwyn@smoke.BRL.MIL (Doug Gwyn) (08/30/89)
In article <13899@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: > #if EOF != -2 This assumes more than the standard guarantees about EOF. In particular, EOF might be defined as an enumeration constant. That's unlikely, but permitted.
karl@haddock.ima.isc.com (Karl Heuer) (08/31/89)
In article <13899@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >I didn't want to require that <stdio.h> be #included before the header file >that was trying to #define ERROR. (I can't yet depend on ANSI's guarantee >that multiple #inclusions of standard header files are safe, so I didn't have >the header file in question #include <stdio.h> itself. It occurs to me that > #ifndef EOF > #include <stdio.h> > #endif >is probably a safe way to protect against a non-idempotent <stdio.h>...) It works correctly if the user has already done the #include, or if they omit it entirely, but not if they do it *after* #include'g your header. The user needs to be warned not to do that; you can't defend against it without having write permission to stdio.h. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
dfp@cbnewsl.ATT.COM (david.f.prosser) (08/31/89)
In article <10867@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >In article <13899@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve Summit) writes: >> #if EOF != -2 > >This assumes more than the standard guarantees about EOF. >In particular, EOF might be defined as an enumeration constant. >That's unlikely, but permitted. My reading of the pANS says that EOF must be a macro defined in <stdio.h>. However, the integral constant expression that EOF is replaced by may well involve operators or operands that are not valid in #if directives. The pANS has certain macros whose replacement expression are required to be valid #if expression, so this was not an oversight. Dave Prosser ...not an official X3J11 answer...