程序错误[C/C++]

对于初学者而言,一般意义上,程序错误可以分为两类,逻辑错误非逻辑错误。前者是指,程序可以通过编译或链接但运行时不符合预期结果,后者是程序不能通过编译或链接。

乍一看这样的分类非常清楚。不过,当引入语言标准对程序行为的规范时,事情变得复杂了。

例如, ISO C/C++ 中,引起 undefined behavior (未定义行为)的如果是错误,属于以上分类中的哪一种错误——即,引起 undefined behavior 的程序是否需要保证编译或链接的成功?

事实上,这一点在 ISO C 和 ISO C++ 中有微妙不同。

首先,摘录和undefined behavior相关的关键术语定义如下:

ISO C99:

3.4
1 behavior
external appearance or action

3.4.3
1 undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

ISO C++03:

// ISO C++ 并没有明确指定什么是 behavior 。

1.3.2 diagnostic message [defns.diagnostic]
a message belonging to an implementation-defined subset of the implementation’s output messages.

1.3.4 ill-formed program [defns.ill.formed]
input to a C++ implementation that is not a well-formed program (1.3.14).

1.3.12 undefined behavior [defns.undefined]
behavior, such as might arise upon use of an erroneous program construct or erroneous data, for which this International Standard imposes no requirements. Undefined behavior may also be expected when this International Standard omits the description of any explicit definition of behavior. [Note: permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed. ]

1.3.14 well-formed program [defns.well.formed]
a C + + program constructed according to the syntax rules, diagnosable semantic rules, and the One Definition Rule (3.2).

ISO C++0x(N3242):
1.3.6 [defns.diagnostic]

diagnostic message
message belonging to an implementation-defined subset of the implementation’s output messages

1.3.9 [defns.ill.formed]
ill-formed program
program that is not well formed

1.3.24 [defns.undefined]
undefined behavior
behavior for which this International Standard imposes no requirements

[ Note: Undefined behavior may be expected when this International Standard omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data. Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed.
—end note ]

1.3.26 [defns.well.formed]
well-formed program
C++ program constructed according to the syntax rules, diagnosable semantic rules, and the One Definition
Rule (3.2).

  其次,定义以外,其它相关的规则:

ISO C99:

4 Conformance

1 In this International Standard, ‘‘shall’’ is to be interpreted as a requirement on an implementation or on a program; conversely, ‘‘shall not’’ is to be interpreted as a prohibition.

2 If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ‘‘behavior that is undefined’’.

5.1.1.3 Diagnostics
1 A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.8)

8) The intent is that an implementation should identify the nature of, and where possible localize, each violation. Of course, an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. It may also successfully translate an invalid program.

ISO C++03:

1.4 Implementation compliance [intro.compliance]

1 The set of diagnosable rules consists of all syntactic and semantic rules in this International Standard except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior.”
2 Although this International Standard states only requirements on C + + implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs. Such requirements have the following meaning:
— If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute3) that program.
— If a program contains a violation of any diagnosable rule, a conforming implementation shall issue at least one diagnostic message, except that
— If a program contains a violation of a rule for which no diagnostic is required, this International Standard places no requirement on implementations with respect to that program.

3) “Correct execution” can include undefined behavior, depending on the data being processed; see 1.3 and 1.9.

ISO C++0x(N3242):

1.4 Implementation compliance [intro.compliance]
1 The set of diagnosable rules consists of all syntactic and semantic rules in this International Standard except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior.”
2 Although this International Standard states only requirements on C++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs. Such requirements have the following meaning:
— If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute2 that program.
— If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this Standard as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.
— If a program contains a violation of a rule for which no diagnostic is required, this International Standard places no requirement on implementations with respect to that program.

2) “Correct execution” can include undefined behavior, depending on the data being processed; see 1.3 and 1.9.

参考以上规则,有以下结论:

1 ISO C++ 的 undefined behavior 外延更小。undefined behavior 在 ISO C 中是指包括语言实现的行为,包括存在语法错误,无法被编译的程序;而在 ISO C++中,无法被编译链接的程序称为 ill-formed program ,而 undefined behavior 只在 well-formed program 上有意义,因为可以认为,对于前者根本不考虑 behavior ——尽管这个词并没在 ISO C++ 中被定义。

2 相对于 C99 和 C++03 , C++0x 并不把 undefined behavior 作为语言实现需要考虑的“错误”。

  所以,关于通常意义“逻辑错误”的分类法,在具体操作中的确过于笼统了。

posted @ 2014-03-05 13:31  foo__hack  阅读(522)  评论(0编辑  收藏  举报