Aha! ... [the crash happens when compiling with "gcc -fpack-struct"
and not when compiling with gcc without "-fpack-struct"].
Which is odd. As near as I can figure, FILE* points to a struct which
really should not be packed on your machine.
Yes, but this could be precisely the problem.
The C standard tells us only that "FILE" is an object type defined
in <stdio.h>, and "stdin", "stdout", and "stderr" are macros that
expand to expressions that have type "pointer to FILE".
On traditional systems, though, this object type is indeed a
structure type, defined using something along the lines:
typedef struct __sFILE FILE;
struct __sFILE {
various integers and pointers and other fields;
};
Now, if -- as eventually became the case for BSD/OS -- the three
macros for stdin, stdout, and stderr are, say:
extern FILE __sstdin, __sstdout, __sstderr;
#define stdin (&__sstdin)
#define stdout (&__sstdout)
#define stdout (&__sstderr)
then "packing" the __sFILE structure might cause *some* problems,
but not the one encountered here, because (on these traditional
systems) the three separate "extern' variables are resolved correctly
by the linker, and the offsets of structure members appear nowhere
in the sample code (which I snipped, but it does not use the getc()
and putc() macros).
On the other hand, suppose that the three macros are defined like
this:
extern FILE __sstd[3]; /* FILEs for fd's 0 through 2 inclusive */
#define stdin (&__sstd[0])
#define stdout (&__sstd[1])
#define stderr (&__sstd[2])
(as they were originally in BSD/OS, because I did something just
like this for 4.4BSD). Now the size of the struct *does* matter,
because stdout's value happens to be the same byte-level pointer
(on these traditional machines) as ((char *)stdin + sizeof(FILE)).
If you pack the structure, and if this in turn changes the result
of sizeof(FILE), the first value passed to fprintf(stdout, "...\n")
changes bit patterns and is no longer the correct value.
I'm leaning towards compiler bug, simply because your code has no structs.
No directly-visible ones, perhaps, but I would bet money that the
above is the correct explanation for the problem.