Reputation: 1531
Like modifying a CONST int
,
Can I register a specific function to handle run time errors so that this kind of operation just fails instead of terminating the application?
Upvotes: 5
Views: 22299
Reputation: 132984
If you mean C++, there is a certain exception class called runtime_error
. You can catch it with a catch clause:
catch(std::runtime_error& e) {}
However, many things in C and C++ (like modifying a const int) result in undefined behavior. You can't catch them at runtime. You can't catch them, because no exception is thrown (technically, anything may happen, including a throwing of exception (C++ only), but that's not something you can or should hope for).
The solution is to write clean safe code. For that there are many advices listed in many books. :)
Upvotes: 7
Reputation: 8694
I was quite wrong.
Trying to modify a const-qualified variable is indeed undefined behavior and, it appears, has been so for some years. It might or might not generate a run-time error; whether it does or not depends on the platform.
n1570, which is the committee draft for the next iteration of the C standard, gives the rule in section 6.7.3, as @Dietrich Epp patiently pointed out. The wording in that section probably hasn't changed since C89.
I'm extremely sorry for claiming otherwise; and for insulting members of this group. Especially Dietrich.
Now, where can I find some of that delicious, free-range crow?
Upvotes: 1
Reputation: 385108
If I understand correctly, the scenarios that you are talking about are those that (generally) are undefined according to the language.
These scenarios lead to unpredictable results and, as you've noted, these results can sometimes include the program continuing and appearing to "work", or it can crash, or nasal demons can spontaneously come into existence.
If you want to catch the use of undefined behaviour then you can do this in some situations, using tools.
For example, Electric Fence is great at revealing where you're writing to memory that you shouldn't be (though don't activate it in release builds!). Whether this will work for writing to something whose const
ness you casted away will depend on what optimisations have been applied; it's possible that the object will have writeable memory, and it'll be physically impossible to determine that you're actually doing something wrong.
What you're not going to get is a tidy language-layer exception. Since you're going to have to go down the tools route anyway, just apply static and dynamic analysis tools as best you can and profile. There is no foolproof way to suddenly turn on "sanely inform me of all use of Undefined Behaviour".
Upvotes: 0
Reputation: 28099
In C runtime errors generally generate signals that can be handled by signal handlers.
In C++ runtime errors can also be thrown as exceptions that can be caught in a try/catch block.
To continue at some point rather than crashing, you will need to use setjmp/longjmp in the signal handlers - it is not safe to return after catching a signal from a program error
Upvotes: 1
Reputation: 8694
You must know this and it must be that your example is ill considered, but it's worthwhile noting anyway in case somebody gets the wrong idea:
In C, there's no such thing as a const int
(or const
anything else) at run time; const
is purely a compile-time notion. Thus there's no run-time error for modifying a const int
.
Upvotes: 0
Reputation: 213288
Modifying a const
is, according to the specification, "undefined behavior" so the compiler can do anything. In practice, many implementations sometimes generate runtime errors for such code but many do not. It often depends on the nature of the program. Here is an illustration:
#include <stdio.h>
#include <string.h>
typedef int (*fn)(const char *);
extern const fn global_fn_ptr;
extern const char global_string[];
const fn global_fn_ptr = puts;
const char global_string[] = "hello";
int main(int argc, char *argv[])
{
puts("Setting global_fn_ptr to NULL");
*(fn *)&global_fn_ptr = NULL;
puts("Setting string to \"bye\"");
strcpy((char *)global_string, "bye");
return 0;
}
On my system, I get a SIGBUS from modifying the string, but modifying the function works fine. This is due to the peculiar nature of function pointers, whose value is not always determined at runtime so the value must be stored in writable memory.
It is generally not safe to catch a SIGBUS or SIGSEGV in C++ and turn it into an exception. It is also very difficult to correctly longjmp
out of a signal handler — half the code that uses this pattern in C is probably incorrect. The safest option is to let the program terminate immediately, or if you really need this kind of help from the runtime, work very carefully with C code so you can free the appropriate resources in a nonlocal exit — C++ won't do because longjmp
won't call destructors.
Or you can just move to C# or Java, both of which have runtimes that do this for you and garbage collectors that clean up afterwards.
Upvotes: 2
Reputation: 43498
This is operating system specific. The language itself specifies these as undefined behaviour.
In POSIX-compliant operating systems your program can catch a SIGSEGV
signal in case of a restricted memory access, SIGILL
in case of an invalid instruction or SIGFPE
in case of an illegal floating point operation, for example division by zero.
Upvotes: 1