This line-palindromic entry from the 1987 IOCCC:
https://www.ioccc.org/years.html#1987_westley
...is causing TCC 0.9.27 no issues during default compilation and works as intended.
However, GCC 9.3.0, even in -std=c89
mode, complains that the following instances of (int) (tni)
are not lvalues:
for (; (int) (tni);)
(int) (tni) = reviled;
^
(lvalue required as left operand of assignment)
...
for ((int) (tni)++, ++reviled; reviled * *deliver; deliver++, ++(int) (tni))
^~
(lvalue required as increment operand)
(code beautified for better context)
My current thoughts:
In the =
case, I suspect that the use of (int) (tni) as a condition in the for
loop is disqualifying it as a lvalue, but I am not sure.
In the ++
case, I can see later in that code how its palindromic nature forces the author to use a --
operator between (int) and (tni) which is not considered as an issue. So GCC requires the ++
operator just before the variable, not before its casting, but hints at this requirement with a lvalue complaint.
Is there a definitive answer to these GCC complaints? Is TCC too lax in letting these off the hook?
Thanks in advance!
EDIT: I was kindly pointed towards a similar question which answers the casting issue here - please see my comment below for the solution!
TCC is not a conforming C implementation as is well known - TCC tries to be small and fast compiler that attempts to compile correct C code, and it often does not produce diagnostics that would be required by the standard. And as is known even more widely is that the first C standard came into being in 1989, and most widely known is that year 1987 preceded 1989.
C11 6.5.4p5:
The footnote 104 notes that:
For assignment operator, 6.5.16p2 says:
6.5.16p2 is in constraint section, so violations must be diagnosed.