C++捕捉执行时错误怎么解决
本篇内容主要讲解"C++捕捉执行时错误怎么解决",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C++捕捉执行时错误怎么解决"吧!
P.7: Catch run-time errors early 尽早捕捉执行时错误
Reason(原因)
Avoid "mysterious" crashes. Avoid errors leading to (possibly unrecognized) wrong results.
避免"原因不明的"崩溃。避免导致(可能是没有被认识的)错误结果的问题。
Example(示例)
void increment1(int* p, int n) // bad: error-prone
{
for (int i = 0; i < n; ++i) ++p[i];
}
void use1(int m)
{
const int n = 10;
int a[n] = {};
// ...
increment1(a, m); // maybe typo, maybe m <= n is supposed
// but assume that m == 20
// ...
}
这里我们在use1中混入了一个将会引起数据破坏或者崩溃的小错误。指针/数量风格的接口导致increment1()没有办法保护自己免受越界访问的危害。如果我们检查越界访问的下标,那么错误直到访问p[10]时才可能被检出。我们可以修改代码从而更早地进行检查。
void increment2(span
p) {
for (int& x : p) ++x;
}
void use2(int m)
{
const int n = 10;
int a[n] = {};
// ...
increment2({a, m}); // maybe typo, maybe m <= n is supposed
// ...
}
Now, m <= n
can be checked at the point of call (early) rather than later. If all we had was a typo so that we meant to use n
as the bound, the code could be further simplified (eliminating the possibility of an error):
现在,m<=n可以在调用时更早的检查。如果只是一个打字错误,我们本来是想用n作为边界,代码可以更简单(排除错误的可能性):
void use3(int m){ const int n = 10; int a[n] = {}; // ... increment2(a); // the number of elements of a need not be repeated // ...}
Example, bad(反面示例)
Don't repeatedly check the same value. Don't pass structured data as strings:
不要重复检查同一个值,不要将结构化数据作为字符串传递。
Date read_date(istream& is); // read date from istream
Date extract_date(const string& s); // extract date from string
void user1(const string& date) // manipulate date
{
auto d = extract_date(date);
// ...
}
void user2()
{
Date d = read_date(cin);
// ...
user1(d.to_string());
// ...
}
The date is validated twice (by the Date
constructor) and passed as a character string (unstructured data).
date数据被两次检查(被Data类的构造函数)并且作为字符串传递(非构造化数据)
Example(示例)
过度检查代价高昂。有些时候提早检查会显得很愚蠢:你可能永远都用不到那个值或者你可能只会用到数据的一部分,而这一部分又比全体更容易检查。类似地,也不要增加可能改变接口的时间复杂度特性的有效性检查(例如不要向一个时间复杂度为O(1)的接口给增加时间复杂度为O(n)的检查)
class Jet { // Physics says: e * e < x * x + y * y + z * z
float x;
float y;
float z;
float e;
public:
Jet(float x, float y, float z, float e)
:x(x), y(y), z(z), e(e)
{
// Should I check here that the values are physically meaningful?
}
float m() const
{
// Should I handle the degenerate case here?
return sqrt(x * x + y * y + z * z - e * e);
}
???
};
由于测量误差的存在,关于jet的物理定律(e * e < x * x + y * y + z * z
)不是恒定成立的。
示例代码的情况中是否在构造函数中增加检查就是一个令人纠结的问题。
Enforcement(实施建议)
Look at pointers and arrays: Do range-checking early and not repeatedly 找到指针和数组,尽早进行范围检查但不要重复检查
Look at conversions: Eliminate or mark narrowing conversions 找到类型检查,排除或确定进行窄化转换
Look for unchecked values coming from input 找到来此(外部)输入的没有经过检查的数据
Look for structured data (objects of classes with invariants) being converted into strings 找到被转换为字符串的结构化数据(包换约束条件的对象或类)
到此,相信大家对"C++捕捉执行时错误怎么解决"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!