首页 > 解决方案 > 在 C 编程中,需要的 L 值是语义错误还是语法错误?

问题描述

1. int main(void) 
2. { 
3.   int a =5, b = 6, c; 
4.   a + b = c; // lvalue required error
5.   2 = a ;     //lvalue required error
6. } 

第 4 行和第 5 行代码被认为是语法错误还是语义错误?据我说,这些行应该抛出语法错误,但我发现上下文无关语法可以生成它们。

标签: csyntax-errorlanguage-lawyerlvalue

解决方案


正如你所说,这是一个语义错误/约束违规。

C11 6.5.16p2

约束

  1. 赋值运算符应具有可修改的左值作为其左操作数。

C 语法描述不足以区分左值和非左值。

赋值运算符出现的实际产生式是C11 6.5.16p1

unary-expression assignment-operator assignment-expression

并且unary-expression除其他外,还包括在括号中进行任何表达的可能性。

因此,遵循语法的简单解析器确实会为这些无效表​​达式生成正确的解析树,并且需要进一步分析以查看它们是否匹配标准中的约束。

即使是最简单的情况,比如

foo = 5;

可能有效也可能无效 - 取决于是否foo是可修改的左值以及是否5可分配给类型为的可修改值而foo无需强制转换...


然而,有一件小事。生产

unary-expression assignment-operator assignment-expression

只允许左侧的一元异常。它不允许无a + b括号出现在 LHS 上!我尝试过的所有 C 编译器(GCC、MSVC、clang)似乎都有一些可疑的地方。可能他们都使用 C++ 语法,然后排除了不可能的情况。在 C++ 中,

a + b

可以返回一个可变引用,因此应该允许出现在左侧。


推荐阅读