0

When writing code in C, is it good style to use -1 and EOF interchangeably? Does the standard guarantee that EOF is -1? Or is the value implementation defined?

For example, if a function returns EOF in certain cases, is it good style to test if the function has returned -1?

If a function returns -1 in certain cases, is it good style to test if the function has returned EOF?

Bakuriu
  • 98,325
  • 22
  • 197
  • 231
David
  • 363
  • 1
  • 4
  • 19
  • 2
    You check for ... whatever the documentation for the method tells you it returns. – Brian Roach Mar 02 '14 at 01:01
  • 1
    Magic numbers are never good style. If there's a named constant available, use that. – Andon M. Coleman Mar 02 '14 at 01:01
  • Maybe I am wrong but isn't EOF '\0' character? – Andres Mar 02 '14 at 01:01
  • 3
    @Andres Correct, you are wrong ;) There is no EOF "character"; it's a specific value returned from a function indicating that the end of an input has been reached. – Brian Roach Mar 02 '14 at 01:02
  • Why use -1 when a constant is available? – Ed Heal Mar 02 '14 at 01:05
  • @Andres: No, it's not the `'\0'` character. `'\0'` marks the end of a string in memory. `EOF` is a value returned by `getchar()` and similar functions to denote the end of a file (or an error condition); it specifically is *not* a character value. – Keith Thompson Mar 02 '14 at 01:06
  • @Ed Heal if a function (one in the standard c library) returns a -1, is it better to use the EOF constant, or -1? – David Mar 02 '14 at 01:13
  • 4
    @David: If the documentation doesn't mention `EOF` don't use `EOF`. – Keith Thompson Mar 02 '14 at 01:32
  • @EdHeal - portability. Unless the EOF constant is *specified* to always be -1, then when you use the constant in your code, it *could* be something else (e.g. -2, or MIN_INT) ... depending on the platform you compiled it for. Then your supposed test for -1 is broken on that platform. Now if >>you<< declare the constant, you don't need to worry about that ... but you still need to be careful mixing >>your<< EOF with APIs that are going to return the value of the standard EOF. (In other words, you've just *hidden* the problem!!) – Stephen C Mar 02 '14 at 01:43
  • If baffles me that anyone would ask this question. Why isn't it intuitively obvious that EOF and -1 should not be interchanged just because they happen to have the same value (which, BTW, they need not)? Checking the return value of getopt for EOF isn't just bad style, it isn't "style" at all, it's a complete conceptual failure. I would fire on the spot anyone I saw doing that. – Jim Balter Mar 02 '14 at 02:18
  • I ask because the android source code contains this exact mistake of checking if a function which returns -1 is returning EOF and as a beginner I wanted to make sure there wasn't some convention or style I was unaware of before submitting a patch, especially considering the author of the code – David Mar 02 '14 at 02:24
  • 1
    Regardless of who the author of that code is, it is a violation of basic principles of abstraction. What is the function? Does the return value signal the end of an input stream? That, after all, is what EOF *means*. At best this was just a brain fart on the part of the author; do *not* emulate it! – Jim Balter Mar 02 '14 at 02:26
  • 1
    Addendum: Apparently, prior to 1992, getopt was defined to return EOF rather than -1. When it was standardized for POSIX, it was changed to -1 so that inclusion of stdio.h would not be necessary. – Jim Balter Mar 02 '14 at 02:34
  • 1
    More on this ... from mirbsd.org/htman/i386/man3/getopt.htm "The getopt() function was once specified to return EOF instead of -1. This was changed by IEEE Std 1003.2-1992 ("POSIX.2") to decouple getopt() from ." – Jim Balter Mar 02 '14 at 02:43

1 Answers1

9

No, EOF most certainly is not guaranteed to be -1.

It's a macro, defined in <stdio.h>,

which expands to an integer constant expression, with type int and a negative value, that is returned by several functions to indicate end-of-file, that is, no more input from a stream

(quoting from section 7.21.1 of the ISO C standard).

I've never seen an implementation where EOF has a value other than -1 -- but then I haven't bothered to check.

Using EOF rather than a literal -1 avoids having your code break on an implementation that chooses a different negative value, but far more importantly it's clear to the reader. If I see -1 in your code, I won't be sure why you chose that particular value. If I see EOF, I know exactly what you meant. (This would apply even if the standard required EOF to have the value -1.)

As for "magic numbers" in general, there are some times when they're unavoidable. An example from the comments: the getopt function is documented to return -1 in certain circumstances, so you should compare its result to -1, not to EOF. Avoid magic numbers when you can, but if the documentation uses them, you're pretty much stuck with them.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • I'm interested in the 'magic number' issue in my second question. I'm thinking in particular about the getopt function which returns -1 if no options are remaining, is it good style to test for an EOF? – David Mar 02 '14 at 01:10
  • 4
    @David: The documentation for `getopt` says that it returns `-1` in certain circumstances, so you should compare the result against `-1`. It would be nice if the header that declares `getopt` defined a named constant, but it doesn't. If a function is documented to return `EOF`, compare its result to `EOF`. If your code depends on `EOF` having a specific value, that's a problem in your code. – Keith Thompson Mar 02 '14 at 01:16
  • *"... is it good style to test for an EOF"* - No. It is not even correct. It is only good style if the official POSIX documentation *states* that the function returns (the standard) EOF. – Stephen C Mar 02 '14 at 01:39
  • From googling around, apparently getopt was documented to return EOF originally, but this was changed in 1992. See, e.g., the RATIONALE section of http://pubs.opengroup.org/onlinepubs/009695399/functions/getopt.html – Jim Balter Mar 02 '14 at 02:36
  • @David Also see BUGS in https://www.mirbsd.org/htman/i386/man3/getopt.htm " The getopt() function was once specified to return EOF instead of -1. This was changed by IEEE Std 1003.2-1992 ("POSIX.2") to decouple getopt() from ." – Jim Balter Mar 02 '14 at 02:42