问题描述
这是1987年IOCCC的线回文录:
https://www.ioccc.org/years.html#1987_westley
...正在导致TCC 0.9.27在默认编译期间没有问题,并按预期工作。
但是,即使在-std=c89
模式下,GCC 9.3.0仍抱怨(int) (tni)
的以下实例不是左值:
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)
(美化代码以获得更好的上下文)
我目前的想法:
在=
情况下,我怀疑在for
循环中使用(int)(tni)作为条件将其取消为左值,但我不确定。>
在++
情况下,我可以在该代码的稍后部分看到其回文性质如何迫使作者在(int)和(tni)之间使用--
运算符,这不被视为问题。因此,GCC要求++
运算符就在变量之前,而不是在变量之前,但是会以左值投诉提示这一要求。
这些GCC投诉是否有明确答案? TCC是否太松懈了?
谢谢!
编辑:有人向我指出了一个类似的问题,该问题在这里回答了强制转换问题-请参阅下面的评论以获取解决方案!
解决方法
TCC不是众所周知的符合C的实现-TCC试图成为又小又快的编译器,尝试编译正确的C代码,并且通常不会产生诊断所需要的诊断信息标准。更广为人知的是,第一个C标准于1989年出现,而最广为人知的是1989年之前的1987年。
- 在表达式前面加上括号类型名称可以将表达式的值转换为命名类型。这种结构称为石膏。 104)不指定任何转换的类型转换对表达式的类型或值没有影响。
脚注104指出:
- 强制转换不会产生左值。因此,强制转换为合格类型与强制转换为非限定版本具有相同的作用。
对于赋值运算符,6.5.16p2说:
- 赋值运算符的左操作数应为可修改的左值。
6.5.16p2位于约束部分,因此必须诊断违反 。