In Python, when we access an index out of the array range we get an error output that gives the exact location in the code that had this error:
array = []
index = 0
array[index]
IndexError Traceback (most recent call last)
Untitled-1 in <cell line: 3>()
1 array = []
2 index = 0
----> 3 array[index]
IndexError: list index out of range
But a code like this in C only gives us a generic address boundary error in both GCC and Clang compiler:
#include <vector>
int main(int argc, const char **argv) {
std::vector<int> array{};
int index = 0;
int value = array[index];
return 0;
}
Is there a way to have better runtime errors with more detail in C ??
CodePudding user response:
only give us a generic Address boundary error
No, it isn't even guaranteed to do that. Accessing out-of-bounds with []
causes undefined behavior in C . If it happens you loose any guarantee on the program's behavior. It may fail with some kind of error, but it might also just continue running producing wrong output or do anything else. This is a very important difference from Python that must be understood. In C if you violate language rules or preconditions of library functions there is no guarantee that the compiler or the program will tell you about it. It will just not behave as expected in many cases.
To figure out where such an error comes from you usually run your program under a debugger which will tell you the line that e.g. a segmentation fault (if one happened) occurred and allows you to step through the code.
You can guarantee that indexing a std::vector
out-of-bounds will generate an error message by using its .at
member function instead of indexing with brackets. If the index is then out-of-bounds an exception will be thrown which you can catch or let propagate out of main
to terminate the program with some error message. However, the exception doesn't typically carry information about the point at which it was thrown. Again you'll need to run under a debugger to get that information.
Depending on your compiler and platform, if you keep using []
, you may also be able to compile your program with a sanitizer enabled which will print a diagnostic including source lines when such an out-of-bounds access occurs. For example GCC and Clang have the address sanitizer which can be enabled with -fsanitize=address
at compile-time. The option -g
should be added as well to generate debug symbols that will be used in the sanitizer output to reference the source locations.