7

POSIX defines EOF as a macro expanding to a negative value:

The header shall define the following macro which shall expand to an integer constant expression with type int and a negative value:

EOF

End-of-file return value.

In every implementation I could find, EOF is always defined as -1.

Although the standard does allow for different values, I could not find any specific implementation where that happens, and I'd like to find one for testing purposes.1

1 I could make my own implementation, but my real purpose is to "find it in the wild", which, due to the impossibility of proving its absence, is the next best thing I can think of.

An almost identical question has already been asked, however there were two questions asked at the end, and the accepted answer only answers the second one (about WEOF). A different user replied to the first question in the negative, but because the question was restricted to common C environments, the negative is arguable correct: -1 is likely to be used in any sensible implementation with small char type.

Since my question is about existence, the only way to actually answer it is to provide an example, so I will rephrase it: please provide an example of an existing implementation where EOF != -1. Be it newlib or musl, PDP or VAX, Plan 9 or Hurd, any combination of libc/hardware/operating system with a POSIX-compatible or ISO C-compatible libc where this happens is valid.

phuclv
  • 37,963
  • 15
  • 156
  • 475
anol
  • 8,264
  • 3
  • 34
  • 78
  • 7
    assume it's `-1` and move on to more interesting challenges – bolov Feb 02 '18 at 12:53
  • 15
    @bolov *assume it's `-1` and move on to more interesting challenges* I'd state that as "Just use `EOF` and move on..." – Andrew Henle Feb 02 '18 at 12:57
  • 2
    *Just do not include your own personal library that you coded just to answer this question.* Why would that be any less valid than stumbling across an implementation one *other* person just happened to post to the internet? It's an artificial situation either way. – Andrew Henle Feb 02 '18 at 12:59
  • @AndrewHenle indeed, I rephrased it. If anyone implements a POSIX-compatible libc with EOF != -1, it's acceptable, since it would be useful anyway for the intended purposes. – anol Feb 02 '18 at 13:02
  • EOF' value should use more bits than character to prevent binary character values from being mistakenly interpreted as EOF. Hence it is meaningful to have it set as -1 which is represented as all bits set for signed values. – Antonin GAVREL Feb 02 '18 at 13:09
  • 4
    Just a remark, EOF is not defined by POSIX but by C standard. It shall exist and have a negative value even on non POSIX compliant systems (think about MS/DOS and Windows). – Serge Ballesta Feb 02 '18 at 13:17
  • @SergeBallesta good remark, I rephrased the question to take it into account. – anol Feb 02 '18 at 13:25
  • 2
    OP: just curious, what is the goal of this endeavour? I.e. what difference does it make for you if you find an implementation where EOF != -1? – Morten Jensen Feb 02 '18 at 13:40
  • 2
    Just speculating, but I think the C standard is written like it is because `0xFFFF...` (all ones) is not necessarily -1 on some of the wildly exotic architectures that C allows, such as signed magnitude. – Lundin Feb 02 '18 at 14:29
  • 2
    I suspect you will find a non-2's complement machine before you will find a compliant `EOF != -1`. – chux - Reinstate Monica Feb 02 '18 at 14:46
  • Amongst other problems, a value of EOF other than -1 makes it harder to write the functions defined by `` as macros. Using -1 makes that simpler. – Jonathan Leffler Feb 02 '18 at 15:05
  • You can implement your lib with EOF = -17 and it will be correct from the specification's point of view. Maybe some other programs will stop working correctly because they silently use -1 instead of EOF. :) I would agree that implementation EOF = -1 is chosen due to compatibility. But no one should rely on it – rhaport May 11 '18 at 05:48
  • EOF is not an implementation. It is a defined numerical constant. – machine_1 Jun 17 '18 at 10:33
  • Unfortunately the [one's complement Unisys systems also use `-1` for EOF](https://stackoverflow.com/a/6972551/995714). From its manual: *The header declares several functions useful for testing and mapping characters. In all cases, the argument is an int. The value of the int must be representable as an unsigned char or must equal the value of the macro EOF. The value must be between –1 and 511. If the argument has any other value, the behavior is undefined.* – phuclv Jun 18 '18 at 04:48
  • You have got an answer from alk now, but I'm not convinced it works. If it doesn't: it will not be possible to conclusively prove a negative, but: ["EOF is -1 on every implementation I've ever heard of" -- Keith Thompson](https://groups.google.com/forum/#!original/comp.lang.c/iMoDhAKQiC4/iNJ3pczEb6IJ) –  Jun 18 '18 at 05:48

1 Answers1

4

Lazy Sunday, so I found this https://github.com/xinu-os/xinu which comes with this https://github.com/xinu-os/xinu/blob/master/include/stddef.h listing this

#define EOF (-2) /**< End-of-file (usually from read)    */

:-)

Xinu sources dated back to 1987 are here: https://www.tuhs.org//cgi-bin/utree.pl?file=Xinu7 which unfortunately seem to be using -1 as value for EOF. :-(

alk
  • 69,737
  • 10
  • 105
  • 255
  • 1
    *Lazy Sunday...* LOL. [This seems somehow apropos.](https://www.youtube.com/watch?reload=9&v=5XcKBmdfpWs) ;-) – Andrew Henle Jun 17 '18 at 11:30
  • @AndrewHenle: My brother is a mechanical engineer and in his free time digs around in old cars, houses, caves ... I am not to different just in my domain ... ;-) – alk Jun 17 '18 at 11:35
  • Reading the rest of this stddef.h file, this doesn't seem like C's stddef.h, not in the least because EOF isn't supposed to be defined there. Are you sure this EOF is used the way standard C's EOF is? –  Jun 18 '18 at 05:43
  • 1
    @hvd: It probably isn't for the historic implementation, which I mentioned. Still, for the re-implementation as per github's sources as linked above, they seem to be using `-2` for `EOF`. Have a look at `lib/libxc/fgetc.c` or `lib/libxc/sscanf.c` and follow the includes. – alk Jun 18 '18 at 06:12
  • @alk That's definitely not C's `fgetc`: it takes an `int`! –  Jun 18 '18 at 06:50