Reputation: 747
I've been studying C++ for two months and now I'm studying the chapter in my book (Programming Principles and Practice using C++) about errors. But after studying the first pages I have a question: what is the difference between a runtime error and a logic error? According to my book a runtime error is an error found by checks at runtime and we can further classify runtime errors as:
while logic errors are simply errors found by the programmer looking for the causes of erroneous results.
I thought I had understood this difference but then an example provided by the author created doubts in me. This is the example:
#include "std_lib_facilities.h"
int area(int lenght, int width) // calculate area of rectangle
{
return lenght * width;
}
int framed_area(int x, int y) // calculate area within frame
{
return area(x - 2, y - 2);
}
int main()
{
int x = -1;
int y = 2;
int z = 4;
int area1 = area(x, y);
int area2 = framed_area(1, z);
int area3 = framed_area(y, z);
double ratio = double(area1) / area3;
}
Here is what the author briefly says about this example :
the calls of the function area() and framed_area() lead to negative values, representing areas, being assigned to area1 and area2. Should we accept such erroneous results? But before answering these question look at the calculation of ratio, in the calculation of ratio area3 will be 0 and the division with 0 will lead to hardware-detected error that terminates the program with some cryptic message. This is the kind of error that you, or your user, will have to deal with if you don't detect and deal sensibly with runtime errors.
What I don't understand here is why a negative value used as an argument for a function that calculates the area is treated as a runtime error, isn't it just a logic error? I thought that runtime errors were only errors due for example by dividing a number by 0 and other special cases. Am I wrong or am I just misunderstanding something? What is the real difference between logic errors and runtime errors? Could you show me some little examples?
Upvotes: 10
Views: 20451
Reputation: 1
Runtime error is happening when your computer system(operating system and / or firmware) has to handle unpredicted instructions. Most of the time, your program is crashed when a runtime error is occurred. For example, a memory leak which is an allocation of new memory that is never deallocated. However, logic error can be easily recognized when you have an unpredicted behavior in your program. Let's say you expect your program to add two numbers but instead it multiplies them. This is a type of logic error that can be fixed just by using the right operator.
Hopefully this helps
Upvotes: 0
Reputation: 181
From my experience with myself :) …
The confusion may stem from our “making life simple” by re-using std exception logic when we are supposed to build one for ourselves. The std exceptions are to be caught (not thrown) by our code. They inform us what has happened when calling a function from the std library and the logic of the exception inheritance tree is not simply transferable outside the library.
std::runtime_error
tells us Huh! Something unpredictable has happed
std::logic_error
tells us Ohoh! You omitted something important in your code
Your boss can write a program like
try { mainCall(); }
catch (const std::logic_error &) { std::cout << "No premiums this year!"; }
catch(const std::runtime_error &) { std::cout << "I know it’s not your fault..."; }
Now the problem arises when we want to re-use this logic in our code. The exceptions are there, ready for use, with the std::string
constructors and the .what()
method, so why to reinvent the wheel, right?
Now the dilemma comes:
double a,b;
std::cin >> a;
std::cin >> b;
if (b == 0) EXCEPTION;
else std::cout << a/b;
So what is the EXCEPTION
like? Is it a runtime_error
or a logic_error
?
runtime_error
.logic_error
either.We intuitively tend to assign runtime_errors
to hardware errors and logic_errors
to “logical” errors – thus one would opt for logic_error
in the example above. But intuition is often a bad guide in programing... just supply your code into your boss’ test unit ;)
Derive your own exception tree starting from the std::exception (or whatever) or do not try to solve the runtime/logic_error dilemma. It does not have a solution outside the std library domain…
Upvotes: -1
Reputation: 1
A runtime error may legitimately happen: e.g. some file containing garbage data, or some wrong human input, or some lack of resource (no more memory, disk space full, broken hardware, network connection failure).
A logic error (or a failing assert
....) is by definition always the symptom of some bug in the program, e.g. a supposedly sorted array used for dichotomical access which happens to be unsorted.
See the documentation of <stdexcept>
header:
std::logic_error: This class defines the type of objects thrown as exceptions to report errors in the internal logical of the program, such as violation of logical preconditions or class invariants.
std::runtime_error: This class defines the type of objects thrown as exceptions to report errors that can only be detected during runtime.
I believe that internal logical for std::logic_error
is a typo, I understand it as internal logic (of the program), but I am not a native English speaker.
If you formalize the specification of your program (e.g. with the help of Frama C using ACSL), you might find (and perhaps correct) logic errors; but you should care about runtime errors. But you could also have bugs in specification.
Read about Ariane 5 flight 501 failure. And look into J.Pitrat's blog to get some other views.
Upvotes: 14
Reputation: 1
#include <iostream>
using std::cout;
using namespace std;
int area(int lenght, int width) // calculate area of rectangle
{
return lenght * width;
}
int framed_area(int x, int y) // calculate area within frame
{
return area(x - 2, y - 2);
}
int main()
{
int x = -1;
int y = 2;
int z = 4;
int area1 = area(x, y);
int area2 = framed_area(1, z);
int area3 = framed_area(y, z);
double ratio = double(area1) / area3;
cout<<area1<<endl
<<area2<<endl
<<area3<<endl
<<ratio<<endl;
system("pause");
return 0;
}
How about trying this there is no runtime error,I don't know how you can see the output result without cout .
I am a new leaner too , I think it is important to practice in short periods of time when studying .
This is just my suggestion as two answers above has well explained .
Upvotes: 0
Reputation: 7504
With regards to the example you provided, providing negative input to the method calculating area is a logical error because you already (as the developer of the application) know that this is wrong. But assume that you wrote the method to calculate the area and you gave this to a user who does not know what calculating area is about - he may provide input which is incorrect and this would lead to incorrect results. In this case, it would be a runtime error as the user is unaware and there is no error checking in place.
Upvotes: 1
Reputation: 1123
Logic errors are due to flaws in the thinking of the programmer and are preventable. For example, forgetting to safeguard against out of bounds errors in an array.
Runtime errors, on the other hand, arise from computer architecture and operating system and are beyond the control of the programmer and cannot be predicted easily during coding.
Upvotes: 0
Reputation: 45684
Your book is certainly right in the first sub-division, compile-time vs. run-time.
If you can, make sure you get the former instead of the latter, as it's automatically detected.
It's also right that both can be further sub-divided, but let us only look at the latter:
External error: hardware-error / operating-system error
Many of those are expected, like the network being unreliable, a user-file missing, and the like. Often, one can recover from them.
Others are unexpected, and often unrecoverable, like a missing required dependency, unreliable RAM, running out the clock, and the like. Expect to simply crash-and-burn.
Input error: Mangled input-data, missing input-data, whatever.
This should be detected by your application, which depending on severity of the error might substitute defaults, try to recover it or just crash-and-burn.
Logic error: The fundamental assumptions of the program have been found wanting.
Nothing can be depended on to hold any longer, the only sane option is to crash-and-burn immediately to try and contain the damage.
Common logic-errors are fencepost-errors (off-by-one), race-conditions, use-after-free and the like.
Be aware that std::logic_error
, despite its name, need not always signify a fatal breakdown in the programs logic, and thus might be expected and relatively benign.
Upvotes: 2