C语言 语义错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2816238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Semantic errors
提问by Gautam Kumar
Can semantic errors be detected by the compiler or not? If not when do the errors get detected?
编译器能否检测到语义错误?如果不是什么时候检测到错误?
As far as I know semantic errors are those errors which result from the expressions involving operators with incorrect number/type of operands.
据我所知,语义错误是由涉及操作数/类型不正确的运算符的表达式引起的那些错误。
For example:
例如:
n3=n1*n2;//n1 is integer, n2 is a string, n3 is an integer
The above statement is semantically incorrect.
上述语句在语义上是不正确的。
But while reading C Primer Plus by Stephen Prata I found the following statement
但是在阅读 Stephen Prata 的 C Primer Plus 时,我发现了以下声明
The compiler does not detect semantic errors, because they don't violate C rules. The compiler has no way of divining your true intentions. That leaves it to you to find these kinds of errors. One way is to compare what a program does to what you expected it to do.
编译器不会检测语义错误,因为它们不违反 C 规则。编译器无法预测您的真实意图。这让您可以找到这些类型的错误。一种方法是将程序所做的事情与您期望它做的事情进行比较。
If not the compiler, who detects those errors?
如果不是编译器,谁会检测到这些错误?
Am I missing something?
我错过了什么吗?
采纳答案by detly
The word "semantic" is ambiguous, and you've encountered two slightly different meanings in these different contexts.
“语义”这个词是模棱两可的,您在这些不同的上下文中遇到了两种略有不同的含义。
The first meaning (your code) is related to how a compiler interprets the code you type. But there are varying degrees of interpretation for this - syntax is one level, where interpretation is simply deciding that n1*n2means you want to perform multiplication. But there is also a higher level of interpretation here - if n1is an integer, and n2is floating point, what is the result? What if I cast it, should it be rounded, truncated, etc? These are "semantic" questions rather than syntactic ones, but someone, somewhere, decided that yes, the compiler can answer these for most people.
第一个含义(您的代码)与编译器如何解释您键入的代码有关。但是对此有不同程度的解释 - 语法是一个级别,其中解释只是决定n1*n2您要执行乘法。但是这里也有更高层次的解释——如果n1是整数,并且n2是浮点数,结果是什么?如果我投射它,它应该被四舍五入,截断等吗?这些是“语义”问题而不是句法问题,但有人在某个地方认为是的,编译器可以为大多数人回答这些问题。
They also decided that the compiler has limits to what it can (and should!) interpret. For example, it can decide that casting to an intis a truncation, not rounding, but it can't decide what you really want when you try to multiply an array by a number.
他们还决定编译器对它可以(并且应该!)解释的内容有限制。例如,它可以决定转换为 anint是截断,而不是舍入,但是当您尝试将数组乘以一个数字时,它无法决定您真正想要什么。
(Sometimes people decide that they CAN, though. In Python, [1] * 3 == [1,1,1].)
(虽然有时人们认为他们可以。在 Python 中,[1] * 3 == [1,1,1].)
The second meaning refers to a much wider scope. If the result of that operation is supposed to be sent to a peripheral device that can take values of 0x000 to 0xFFF, and you multiply 0x7FF by 0x010, clearly you've made a semantic error. The designers of the peripheral device must decide whether, or how, to cope with that. You, as a programmer, could also decide to put in some sanity checks. But the compiler has no idea about these external semanticconstraints, or how to enforce them (filter user input? return an error? truncate? wrap?), which is what the second quote is saying.
第二个含义是指更广泛的范围。如果该操作的结果应该发送到可以取 0x000 到 0xFFF 值的外围设备,并且您将 0x7FF 乘以 0x010,显然您犯了语义错误。外围设备的设计者必须决定是否或如何应对。作为程序员,您也可以决定进行一些健全性检查。但是编译器不知道这些外部语义约束,或者如何强制执行它们(过滤用户输入?返回错误?截断?换行?),这就是第二个引用所说的。
回答by Michael Mrozek
"Semantic error" is another term for "logic error", where you literally write the wrong code. For example, writing n3=n1*n2when really you wanted to divide -- the compiler has no way to tell that your algorithm should have divided instead of multiplying; you told it to multiply, so it does.
“语义错误”是“逻辑错误”的另一个术语,您实际上编写了错误的代码。例如,n3=n1*n2当你真的想除法时编写——编译器无法告诉你的算法应该除法而不是乘法;你告诉它乘以它,它确实如此。
The error you described in your example is a type safety error, and compilers can catch that during their typechecking phase (if the language is strongly typed)
您在示例中描述的错误是类型安全错误,编译器可以在其类型检查阶段捕获该错误(如果语言是强类型的)
回答by Secure
There are basically three types of errors.
基本上有三种类型的错误。
1) Syntax errors. These are invalid code the compiler doesn't understand, e.g. your example of multiplying a string with an integer in C. The compiler willdetect them, because it can't compile them.
1) 语法错误。这些是编译器无法理解的无效代码,例如您在 C中将字符串与整数相乘的示例。编译器会检测到它们,因为它无法编译它们。
2) Semantic errors. These are valid code the compiler understands, but they do not what you, the programmer, intended. These may be using the wrong variable, the wrong operation, or operations in the wrong order. There is no way for the compiler to detect them.
2) 语义错误。这些是编译器可以理解的有效代码,但它们不是您(程序员)所期望的。这些可能是使用了错误的变量、错误的操作或操作顺序错误。编译器无法检测到它们。
There is a third class, which can be the most expensive:
还有第三类,可能是最贵的:
3) Design errors. The code is correct and bug-free and does exactly what you've intended. But your intentions are wrong, e.g. based on wrong assumptions, wrong models, or you've used the wrong formulars, misunderstood the customer, or such.
3) 设计错误。代码是正确且无错误的,并且完全符合您的意图。但是您的意图是错误的,例如基于错误的假设、错误的模型,或者您使用了错误的公式、误解了客户等。
回答by monn
I think the writer who wrote the book defined "semantic" differently. For most compilers, there is a step involving some semantic checks.
我认为写这本书的作者对“语义”的定义不同。对于大多数编译器,有一个步骤涉及一些语义检查。
Semantic analysis is the phase in which the compiler adds semantic information to the parse tree and builds the symbol table. This phase performs semantic checks such as type checking (checking for type errors), or object binding (associating variable and function references with their definitions), or definite assignment (requiring all local variables to be initialized before use), rejecting incorrect programs or issuing warnings. Semantic analysis usually requires a complete parse tree, meaning that this phase logically follows the parsing phase, and logically precedes the code generation phase, though it is often possible to fold multiple phases into one pass over the code in a compiler implementation.
语义分析是编译器向解析树添加语义信息并构建符号表的阶段。此阶段执行语义检查,例如类型检查(检查类型错误)或对象绑定(将变量和函数引用与其定义相关联)或明确赋值(要求在使用前初始化所有局部变量)、拒绝不正确的程序或发出警告。语义分析通常需要一个完整的解析树,这意味着这个阶段在逻辑上跟在解析阶段之后,在逻辑上在代码生成阶段之前,尽管在编译器实现中通常可以将多个阶段折叠成一次遍历代码。
回答by Midhat
Semantic errors are all those, where your code does something you didn't intend.
语义错误就是那些你的代码做了你不想要的事情。
These errors can be caught by testing or analysis.
这些错误可以通过测试或分析来捕捉。
Analysis means you or a tool looks at your code and try to find out problems. This involves using code reviews and static analyzers.
分析意味着您或某个工具会查看您的代码并尝试找出问题所在。这涉及使用代码和静态分析器。
Testing is when you give your program some inputs that are expected to produce a given output if the program is semantically correct. So If the actual output doesnt match the expected output, the program is semantically incorrect.
测试是当你给你的程序一些输入时,如果程序在语义上是正确的,这些输入会产生给定的输出。因此,如果实际输出与预期输出不匹配,则该程序在语义上是不正确的。
So simply put, it is YOU the developer or tester who is supposed to catch semantic errors.
简单地说,应该捕获语义错误的是开发人员或测试人员。
回答by sum1stolemyname
Actually, multiplying a string and an integer is a syntactic error since the multiplication of incompatible types (such as a string and an integer) is not defined in C.
实际上,将字符串和整数相乘是一个语法错误,因为 C 中没有定义不兼容类型(例如字符串和整数)的乘法。
A semantic error is an error which occurs when your program does compile, but does not do what you want.
语义错误是当您的程序确实编译但没有执行您想要的操作时发生的错误。
回答by R Samuel Klatchko
That quote is talking about things like doing a x <= 1where you really should have done x < 1.
这句话是在谈论诸如做x <= 1你真正应该做的事情之类的事情x < 1。
But for the semantics of the language (not being allowed to add a string and an integer), yes it is the compiler that handles that.
但是对于语言的语义(不允许添加字符串和整数),是的,它是处理它的编译器。
回答by Blindy
That is a syntactic error, which compilers can indeed detect and report.
这是一个语法错误,编译器确实可以检测和报告。
A semantic error is more like something that compiles fine (down to the very types), but isn't what you want it to be. Semantic errors are part of your algorithm more than your actual syntax.
语义错误更像是编译良好的东西(直到非常类型),但不是您想要的。语义错误是算法的一部分,而不是实际语法。
回答by Pascal Cuoq
If not the compiler, who detects those errors?
如果不是编译器,谁会检测到这些错误?
Sometimes, no-one: the compiler does not have to insert any run-time checks that could help notice the error when it happens, and the execution just continues.
有时,没有:编译器不必插入任何运行时检查来帮助在错误发生时注意到错误,并且执行只是继续。
Sometimes, the execution environment: the program accesses an invalid address because of an error, and it is outside the address space that the process can legally access.
有时,执行环境:程序由于错误访问了无效地址,并且在进程可以合法访问的地址空间之外。
You can use complement the compiler with a static analyzer to detect some or all of the errors in a program, but these can also have false positives: they may emit a warning for a piece of code that works without errors.
您可以使用带有静态分析器的补充编译器来检测程序中的部分或全部错误,但这些错误也可能具有误报:它们可能会针对一段正常运行的代码发出警告。
回答by DEADlist
String literals and strings are presented in memory as numbers (bytes/m words or in high-level - shorts, integers). C is low-level programming level, in which all things are approached to machine/assembler level. So multiplication of number on string literal (if it is array, it will be incorrect) is correct, because this string literal will be actually (after compilation) a number.
字符串文字和字符串在内存中显示为数字(字节/米字或高级 - 短,整数)。C是低级编程级别,其中所有事情都接近机器/汇编级别。所以字符串文字上的数字乘法(如果它是数组,它将是不正确的)是正确的,因为这个字符串文字实际上(编译后)是一个数字。

