语义错误

Gau*_*mar 6 c

编译器是否可以检测到语义错误?如果不是,何时检测到错误?

据我所知,语义错误是由涉及操作数不正确/操作数类型的运算符的表达式产生的错误.

例如:

n3=n1*n2;//n1 is integer, n2 is a string, n3 is an integer
Run Code Online (Sandbox Code Playgroud)

上述语句在语义上是不正确的.

但在阅读Stephen Prata的C Primer Plus时,我发现了以下声明

编译器不检测语义错误,因为它们不违反C规则.编译器无法确定您的真实意图.这让你找到这些错误.一种方法是比较程序的功能与预期功能.

如果不是编译器,谁检测到这些错误?

我错过了什么吗?

Mic*_*zek 5

"语义错误"是"逻辑错误"的另一个术语,您可以在其中编写错误的代码.例如,n3=n1*n2当你想要划分的时候写- 编译器没有办法告诉你的算法应该划分而不是乘法; 你告诉它要增加,所以确实如此.

您在示例中描述的错误是类型安全错误,编译器可以在其类型检查阶段捕获该错误(如果语言是强类型的)

  • 这取决于你如何使用这些词,我认为大多数编译人员会不同意这个答案.编译器通常被视为由几个"阶段"组成.一种是语法分析,通常称为"解析器",可以捕获语法错误.此示例不是语法错误.另一个阶段是语义分析,它主要处理数据类型,并且可以捕获类型错误,例如这个.因此,这种类型的错误通常称为语义错误. (2认同)

det*_*tly 5

"语义"这个词含糊不清,你在这些不同的语境中遇到了两个略有不同的含义.

第一个含义(您的代码)与编译器如何解释您键入的代码有关.但是对此有不同程度的解释 - 语法是一个层次,解释只是决定n1*n2你想要执行乘法.但是这里也有更高级别的解释 - 如果n1是整数,并且n2是浮点数,结果是什么?如果我施放它,它应该是圆形的,截断的等等怎么办?这些是"语义"问题而不是语法问题,但有人在某处决定是,编译器可以为大多数人回答这些问题.

他们还决定编译器对它可以(并且应该!)解释的内容有限制.例如,它可以决定转换为a int是截断,而不是舍入,但是当您尝试将数组乘以数字时,它无法确定您真正想要的是什么.

(有时人们会认为他们可以.但在Python中,[1] * 3 == [1,1,1].)

第二个含义涉及更广泛的范围.如果该操作的结果应该被发送到可以取值0x000到0xFFF的外围设备,并且你将0x7FF乘以0x010,显然你已经出现了语义错误.外围设备的设计者必须决定是否或如何应对.作为程序员,您也可以决定进行一些健全性检查.但是编译器不知道这些外部语义约束,或者如何强制它们(过滤用户输入?返回错误?truncate?wrap?),这就是第二个引用所说的内容.