在C编程中,所需的L值是语义错误还是语法错误?

use*_*873 1 c syntax-error lvalue language-lawyer

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. } 
Run Code Online (Sandbox Code Playgroud)

第4行和第5行代码被视为语法错误或语义错误?据我说,这些行应该抛出语法错误,但我发现Context Free Grammar可以生成它们.

Ant*_*ala 6

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

C11 6.5.16p2

约束

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

C语法描述不足以从非左值中识别左值.

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

unary-expression assignment-operator assignment-expression
Run Code Online (Sandbox Code Playgroud)

并且unary-expression在其他一切中包括在括号中表达任何表达的可能性.

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

即使是最简单的情况,如

foo = 5;
Run Code Online (Sandbox Code Playgroud)

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


但是,有一件小事.生产

unary-expression assignment-operator assignment-expression
Run Code Online (Sandbox Code Playgroud)

只允许左侧的一元例外.它不允许a + b出现在LHS上不显眼!我尝试过的所有C编译器似乎都有些可疑(GCC,MSVC,clang).可能是所有人都使用C++语法,然后清除了不可能性.在C++中,

a + b
Run Code Online (Sandbox Code Playgroud)

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