On 07/18/2017 02:46 PM, Dennis Clarke wrote:
Do you have 0x0A at the end of your text file ?
No:
zira:~> hd tst.c
00000000 69 6e 74 20 6d 61 69 6e 20 28 76 6f 69 64 29 0a |int main
(void).|
00000010 7b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a |{.
return 0;.}.|
00000020 23 64 65 66 69 6e 65 20 46 4f 4f |#define
FOO|
0000002b
And BTW, Clang behaves as expected:
zira:~> clang-4.0 -std=c99 -pedantic tst.c -o tst
tst.c:5:12: warning: no newline at end of file [-Wnewline-eof]
#define FOO
^
1 warning generated.
So, I think that's a bug in GCC. Do you agree?
I agree. C requires non-empty source files to end in an unescaped
new-line character. POSIX further requires that source files be
text files (and defines the term text file as a file organized
into zero or more lines of at most LINE_MAX characters each).
C++ 11 (and later) has a weaker requirement that makes the above
test case valid.
Fascinating. I never would have thought that a zero line length file
would be accepted as valid. However gcc ( older rev 4.9.2 ) will
accept this :
$ printf "int main ( int argc, char* argv[] ) { return 0; }" > tzero.c
$ wc tzero.c
0 12 49 tzero.c
$ hdump -Ax -v -tx1 tzero.c
0: 69 6e 74 20 6d 61 69 6e 20 28 20 69 6e 74 20 61
10: 72 67 63 2c 20 63 68 61 72 2a 20 61 72 67 76 5b
20: 5d 20 29 20 7b 20 72 65 74 75 72 6e 20 30 3b 20
30: 7d
31:
$ /usr/local/gcc4/bin/gcc -m64 -std=c99 -pedantic \
-D_TS_ERRNO -D_POSIX_PTHREAD_SEMANTICS \
-D_LARGEFILE64_SOURCE -S -o tzero.s tzero.c
$ cat tzero.s
.file "tzero.c"
.section ".text"
.align 4
.global main
.type main, #function
.proc 04
main:
save %sp, -176, %sp
mov %i0, %g1
stx %i1, [%fp+2183]
st %g1, [%fp+2175]
mov 0, %g1
sra %g1, 0, %g1
mov %g1, %i0
return %i7+8
nop
.size main, .-main
.ident "GCC: (genunix Fri Jan 2 11:56:03 GMT 2015) 4.9.2"
Whereas c99 ( Oracle Studio 12.4 ) rejects the input file :
$ c99 -errfmt=error -erroff=%none -errshort=full \
-m64 -xmemalign=8s -xnolibmil -Xc -xregs=no%appl -xlibmieee \
-Qy -xbuiltin=%none -D_TS_ERRNO -D_POSIX_PTHREAD_SEMANTICS \
-D_LARGEFILE64_SOURCE -S -o tzero.s tzero.c
"tzero.c", line 1: warning: newline not last character in file
I think "zero or more lines of at most LINE_MAX characters each" won't
work. There must be more than "zero lines" in the input. What is the
actual spec?
Yes, C requires every non-empty source file to have at least
one line. The C11 standard says in 5.1.1.2 Translation phases,
p2:
A source file that is not empty shall end in a new-line character,
which shall not be immediately preceded by a backslash character
before any such splicing takes place.
The POSIX specification for the c99 command specifies that its
input be a text file:
pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html#tag_20_11_07
with Text File being defined here:
pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_403
The C++ requirement is also in Phases of translation:
A source file that is not empty and that does not end in
a new-line character, or that ends in a new-line character
immediately preceded by a backslash character before any such
splicing takes place, shall be processed as if an additional
new-line character were appended to the file.
This is really splitting hairs of course.
It actually has been a source of subtle bugs. POSIX defines
the behavior of most utilities (e.g., awk, grep, and sed) for
text files but not for others. Some implementations (I think
even some GNU utilities) don't behave the same way when their
input doesn't meet that requirement. Being undefined, their
behavior can be pretty bizarre (i.e., it's not constrained
to justnot processing the remainder of the file past the last
newline, but can extend to the lines prior to it).
Martin