Related
The following code does not catch an exception, when I try to divide by 0. Do I need to throw an exception, or does the computer automatically throw one at runtime?
int i = 0;
cin >> i; // what if someone enters zero?
try {
i = 5/i;
}
catch (std::logic_error e) {
cerr << e.what();
}
You need to check it yourself and throw an exception. Integer divide by zero is not an exception in standard C++.
Neither is floating point divide by zero but at least that has specific means for dealing with it.
The exceptions listed in the ISO standard are:
namespace std {
class logic_error;
class domain_error;
class invalid_argument;
class length_error;
class out_of_range;
class runtime_error;
class range_error;
class overflow_error;
class underflow_error;
}
and you could argue quite cogently that either overflow_error (the infinity generated by IEEE754 floating point could be considered overflow) or domain_error (it is a problem with the input value) would be ideal for indicating a divide by zero.
However, section 5.6 (of C++11, though I don't think this has changed from the previous iteration) specifically states:
If the second operand of / or % is zero, the behavior is undefined.
So, it could throw those (or any other) exceptions. It could also format your hard disk and laugh derisively :-)
If you wanted to implement such a beast, you could use something like intDivEx in the following program (using the overflow variant):
#include <iostream>
#include <stdexcept>
// Integer division/remainder, catching divide by zero.
inline int intDivEx (int numerator, int denominator) {
if (denominator == 0)
throw std::overflow_error("Divide by zero exception");
return numerator / denominator;
}
inline int intModEx (int numerator, int denominator) {
if (denominator == 0)
throw std::overflow_error("Divide by zero exception");
return numerator % denominator;
}
int main (void) {
int i = 42;
try { i = intDivEx (10, 0); }
catch (std::overflow_error &e) {
std::cout << e.what() << " -> ";
}
std::cout << i << std::endl;
try { i = intDivEx (10, 2); }
catch (std::overflow_error &e) {
std::cout << e.what() << " -> ";
}
std::cout << i << std::endl;
return 0;
}
This outputs:
Divide by zero exception -> 42
5
and you can see it throws and catches the exception (leaving the return variable untouched) for the divide by zero case.
The % equivalent is almost exactly the same:
Updated with comments from ExcessPhase
GCC (at least version 4.8) will let you emulate this behaviour:
#include <signal.h>
#include <memory>
#include <iostream>
int main() {
std::shared_ptr<void(int)> handler(
signal(SIGFPE, [](int signum) {throw std::logic_error("FPE"); }),
[](__sighandler_t f) { signal(SIGFPE, f); });
int i = 0;
std::cin >> i; // what if someone enters zero?
try {
i = 5/i;
}
catch (std::logic_error e) {
std::cerr << e.what();
}
}
This sets up a new signal handler which throws an exception, and a shared_ptr to the old signal handler, with a custom 'deletion' function that restores the old handler when it goes out of scope.
You need to compile with at least these options:
g++ -c Foo.cc -o Foo.o -fnon-call-exceptions -std=c++11
Visual C++ will also let you do something similar:
#include <eh.h>
#include <memory>
int main() {
std::shared_ptr<void(unsigned, EXCEPTION_POINTERS*)> handler(
_set_se_translator([](unsigned u, EXCEPTION_POINTERS* p) {
switch(u) {
case FLT_DIVIDE_BY_ZERO:
case INT_DIVIDE_BY_ZERO:
throw std::logic_error("Divide by zero");
break;
...
default:
throw std::logic_error("SEH exception");
}
}),
[](_se_translator_function f) { _set_se_translator(f); });
int i = 0;
try {
i = 5 / i;
} catch(std::logic_error e) {
std::cerr << e.what();
}
}
And of course you can skip all the C++11-ishness of this and put them in a traditional RAII-managing struct.
As far as I know C++ specifications does not mention anything about divide by zero exeption. I believe you need to do it yourself...
Stroustrup says, in "The Design and Evolution of C++" (Addison Wesley, 1994), "low-level events, such as arithmetic overflows and divide by zero, are assumed to be handled by a dedicated lower-level mechanism rather than by exceptions. This enables C++ to match the behaviour of other languages when it comes to arithmetic. It also avoids the problems that occur on heavily pipelined architectures where events such as divide by zero are asynchronous."`
You need to throw the exception manually using throw keyword.
Example:
#include <iostream>
using namespace std;
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
int main ()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
You should check if i = 0 and not divide then.
(Optionally after checking it you can throw an exception and handle it later).
More info at: http://www.cprogramming.com/tutorial/exceptions.html
setjmp + longjmp
https://stackoverflow.com/a/25601100/895245 mentioned the possibility or throwing a C++ exception from a signal handler, but Throwing an exception from within a signal handler mentions several caveats of that, so I would be very careful.
As another potentially dangerous possibility, you can also try to use the older C setjmp + longjmp mechanism as shown at: C handle signal SIGFPE and continue execution
main.cpp
#include <csetjmp>
#include <csignal>
#include <cstring>
#include <iostream>
jmp_buf fpe;
void handler(int signum) {
longjmp(fpe, 1);
}
int main() {
volatile int i, j;
for(i = 0; i < 10; i++) {
struct sigaction act;
struct sigaction oldact;
memset(&act, 0, sizeof(act));
act.sa_handler = handler;
act.sa_flags = SA_NODEFER | SA_NOMASK;
sigaction(SIGFPE, &act, &oldact);
if (0 == setjmp(fpe)) {
std::cout << "before divide" << std::endl;
j = i / 0;
sigaction(SIGFPE, &oldact, &act);
} else {
std::cout << "after longjmp" << std::endl;
sigaction(SIGFPE, &oldact, &act);
}
}
return 0;
}
Compile and run:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
Output:
i = 0
before divide
after longjmp
i = 1
before divide
after longjmp
i = 2
before divide
after longjmp
man longjmp says that you can longjmp from signal handlers, but with a few caveats:
POSIX.1-2008 Technical Corrigendum 2 adds longjmp() and siglongjmp() to the list of async-signal-safe functions. However, the standard recommends avoiding the use of these functions from signal handlers and goes on to point
out that if these functions are called from a signal handler that interrupted a call to a non-async-signal-safe function (or some equivalent, such as the steps equivalent to exit(3) that occur upon a return from the initial
call to main()), the behavior is undefined if the program subsequently makes a call to a non-async-signal-safe function. The only way of avoiding undefined behavior is to ensure one of the following:
After long jumping from the signal handler, the program does not call any non-async-signal-safe functions and does not return from the initial call to main().
Any signal whose handler performs a long jump must be blocked during every call to a non-async-signal-safe function and no non-async-signal-safe functions are called after returning from the initial call to main().
See also: Longjmp out of signal handler?
However Throwing an exception from within a signal handler mentions that this has further dangers with C++:
setjmp and longjmp aren't compatible with exceptions and RAII (ctors/dtors), though. :( You'll probably get resource leaks with this.
so you would have to be very very careful with that as well.
I guess the moral is that signal handlers are hard, and you should avoid them as much as possible unless you know exactly what you are doing.
Detect floating point zero division
It is also possible to detect floating point division by zero with a glibc call to:
#include <cfenv>
feenableexcept(FE_INVALID);
as shown at: What is the difference between quiet NaN and signaling NaN?
This makes it raises SIGFPE as well like the integer division by zero instead of just silently qnan and setting flags.
What about this one? Tested with Clang, GCC throws SIGILL.
#include <iostream>
#include <cassert>
int main()
{
unsigned int x = 42;
unsigned int y = x;
y -= x;
x /= y;
std::cout << x << " != "<< *(&x) << std::endl;
assert (*(&x) == x);
}
do i need to throw an exception or does the computer automatically throws one at runtime?
Either you need to throw the exception yourself and catch it. e.g.
try {
//...
throw int();
}
catch(int i) { }
Or catch the exception which is thrown by your code.
try {
int *p = new int();
}
catch (std::bad_alloc e) {
cerr << e.what();
}
In your case, I am not sure if is there any standard exception meant for divide by zero. If there is no such exception then you can use,
catch(...) { // catch 'any' exception
}
You can just do assert(2 * i != i) which will throw an assert. You can write your own exception class if you need something fancier.
The following code does not catch an exception, when I try to divide by 0. Do I need to throw an exception, or does the computer automatically throw one at runtime?
int i = 0;
cin >> i; // what if someone enters zero?
try {
i = 5/i;
}
catch (std::logic_error e) {
cerr << e.what();
}
You need to check it yourself and throw an exception. Integer divide by zero is not an exception in standard C++.
Neither is floating point divide by zero but at least that has specific means for dealing with it.
The exceptions listed in the ISO standard are:
namespace std {
class logic_error;
class domain_error;
class invalid_argument;
class length_error;
class out_of_range;
class runtime_error;
class range_error;
class overflow_error;
class underflow_error;
}
and you could argue quite cogently that either overflow_error (the infinity generated by IEEE754 floating point could be considered overflow) or domain_error (it is a problem with the input value) would be ideal for indicating a divide by zero.
However, section 5.6 (of C++11, though I don't think this has changed from the previous iteration) specifically states:
If the second operand of / or % is zero, the behavior is undefined.
So, it could throw those (or any other) exceptions. It could also format your hard disk and laugh derisively :-)
If you wanted to implement such a beast, you could use something like intDivEx in the following program (using the overflow variant):
#include <iostream>
#include <stdexcept>
// Integer division/remainder, catching divide by zero.
inline int intDivEx (int numerator, int denominator) {
if (denominator == 0)
throw std::overflow_error("Divide by zero exception");
return numerator / denominator;
}
inline int intModEx (int numerator, int denominator) {
if (denominator == 0)
throw std::overflow_error("Divide by zero exception");
return numerator % denominator;
}
int main (void) {
int i = 42;
try { i = intDivEx (10, 0); }
catch (std::overflow_error &e) {
std::cout << e.what() << " -> ";
}
std::cout << i << std::endl;
try { i = intDivEx (10, 2); }
catch (std::overflow_error &e) {
std::cout << e.what() << " -> ";
}
std::cout << i << std::endl;
return 0;
}
This outputs:
Divide by zero exception -> 42
5
and you can see it throws and catches the exception (leaving the return variable untouched) for the divide by zero case.
The % equivalent is almost exactly the same:
Updated with comments from ExcessPhase
GCC (at least version 4.8) will let you emulate this behaviour:
#include <signal.h>
#include <memory>
#include <iostream>
int main() {
std::shared_ptr<void(int)> handler(
signal(SIGFPE, [](int signum) {throw std::logic_error("FPE"); }),
[](__sighandler_t f) { signal(SIGFPE, f); });
int i = 0;
std::cin >> i; // what if someone enters zero?
try {
i = 5/i;
}
catch (std::logic_error e) {
std::cerr << e.what();
}
}
This sets up a new signal handler which throws an exception, and a shared_ptr to the old signal handler, with a custom 'deletion' function that restores the old handler when it goes out of scope.
You need to compile with at least these options:
g++ -c Foo.cc -o Foo.o -fnon-call-exceptions -std=c++11
Visual C++ will also let you do something similar:
#include <eh.h>
#include <memory>
int main() {
std::shared_ptr<void(unsigned, EXCEPTION_POINTERS*)> handler(
_set_se_translator([](unsigned u, EXCEPTION_POINTERS* p) {
switch(u) {
case FLT_DIVIDE_BY_ZERO:
case INT_DIVIDE_BY_ZERO:
throw std::logic_error("Divide by zero");
break;
...
default:
throw std::logic_error("SEH exception");
}
}),
[](_se_translator_function f) { _set_se_translator(f); });
int i = 0;
try {
i = 5 / i;
} catch(std::logic_error e) {
std::cerr << e.what();
}
}
And of course you can skip all the C++11-ishness of this and put them in a traditional RAII-managing struct.
As far as I know C++ specifications does not mention anything about divide by zero exeption. I believe you need to do it yourself...
Stroustrup says, in "The Design and Evolution of C++" (Addison Wesley, 1994), "low-level events, such as arithmetic overflows and divide by zero, are assumed to be handled by a dedicated lower-level mechanism rather than by exceptions. This enables C++ to match the behaviour of other languages when it comes to arithmetic. It also avoids the problems that occur on heavily pipelined architectures where events such as divide by zero are asynchronous."`
You need to throw the exception manually using throw keyword.
Example:
#include <iostream>
using namespace std;
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
int main ()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
You should check if i = 0 and not divide then.
(Optionally after checking it you can throw an exception and handle it later).
More info at: http://www.cprogramming.com/tutorial/exceptions.html
setjmp + longjmp
https://stackoverflow.com/a/25601100/895245 mentioned the possibility or throwing a C++ exception from a signal handler, but Throwing an exception from within a signal handler mentions several caveats of that, so I would be very careful.
As another potentially dangerous possibility, you can also try to use the older C setjmp + longjmp mechanism as shown at: C handle signal SIGFPE and continue execution
main.cpp
#include <csetjmp>
#include <csignal>
#include <cstring>
#include <iostream>
jmp_buf fpe;
void handler(int signum) {
longjmp(fpe, 1);
}
int main() {
volatile int i, j;
for(i = 0; i < 10; i++) {
struct sigaction act;
struct sigaction oldact;
memset(&act, 0, sizeof(act));
act.sa_handler = handler;
act.sa_flags = SA_NODEFER | SA_NOMASK;
sigaction(SIGFPE, &act, &oldact);
if (0 == setjmp(fpe)) {
std::cout << "before divide" << std::endl;
j = i / 0;
sigaction(SIGFPE, &oldact, &act);
} else {
std::cout << "after longjmp" << std::endl;
sigaction(SIGFPE, &oldact, &act);
}
}
return 0;
}
Compile and run:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
Output:
i = 0
before divide
after longjmp
i = 1
before divide
after longjmp
i = 2
before divide
after longjmp
man longjmp says that you can longjmp from signal handlers, but with a few caveats:
POSIX.1-2008 Technical Corrigendum 2 adds longjmp() and siglongjmp() to the list of async-signal-safe functions. However, the standard recommends avoiding the use of these functions from signal handlers and goes on to point
out that if these functions are called from a signal handler that interrupted a call to a non-async-signal-safe function (or some equivalent, such as the steps equivalent to exit(3) that occur upon a return from the initial
call to main()), the behavior is undefined if the program subsequently makes a call to a non-async-signal-safe function. The only way of avoiding undefined behavior is to ensure one of the following:
After long jumping from the signal handler, the program does not call any non-async-signal-safe functions and does not return from the initial call to main().
Any signal whose handler performs a long jump must be blocked during every call to a non-async-signal-safe function and no non-async-signal-safe functions are called after returning from the initial call to main().
See also: Longjmp out of signal handler?
However Throwing an exception from within a signal handler mentions that this has further dangers with C++:
setjmp and longjmp aren't compatible with exceptions and RAII (ctors/dtors), though. :( You'll probably get resource leaks with this.
so you would have to be very very careful with that as well.
I guess the moral is that signal handlers are hard, and you should avoid them as much as possible unless you know exactly what you are doing.
Detect floating point zero division
It is also possible to detect floating point division by zero with a glibc call to:
#include <cfenv>
feenableexcept(FE_INVALID);
as shown at: What is the difference between quiet NaN and signaling NaN?
This makes it raises SIGFPE as well like the integer division by zero instead of just silently qnan and setting flags.
What about this one? Tested with Clang, GCC throws SIGILL.
#include <iostream>
#include <cassert>
int main()
{
unsigned int x = 42;
unsigned int y = x;
y -= x;
x /= y;
std::cout << x << " != "<< *(&x) << std::endl;
assert (*(&x) == x);
}
do i need to throw an exception or does the computer automatically throws one at runtime?
Either you need to throw the exception yourself and catch it. e.g.
try {
//...
throw int();
}
catch(int i) { }
Or catch the exception which is thrown by your code.
try {
int *p = new int();
}
catch (std::bad_alloc e) {
cerr << e.what();
}
In your case, I am not sure if is there any standard exception meant for divide by zero. If there is no such exception then you can use,
catch(...) { // catch 'any' exception
}
You can just do assert(2 * i != i) which will throw an assert. You can write your own exception class if you need something fancier.
The following code does not catch an exception, when I try to divide by 0. Do I need to throw an exception, or does the computer automatically throw one at runtime?
int i = 0;
cin >> i; // what if someone enters zero?
try {
i = 5/i;
}
catch (std::logic_error e) {
cerr << e.what();
}
You need to check it yourself and throw an exception. Integer divide by zero is not an exception in standard C++.
Neither is floating point divide by zero but at least that has specific means for dealing with it.
The exceptions listed in the ISO standard are:
namespace std {
class logic_error;
class domain_error;
class invalid_argument;
class length_error;
class out_of_range;
class runtime_error;
class range_error;
class overflow_error;
class underflow_error;
}
and you could argue quite cogently that either overflow_error (the infinity generated by IEEE754 floating point could be considered overflow) or domain_error (it is a problem with the input value) would be ideal for indicating a divide by zero.
However, section 5.6 (of C++11, though I don't think this has changed from the previous iteration) specifically states:
If the second operand of / or % is zero, the behavior is undefined.
So, it could throw those (or any other) exceptions. It could also format your hard disk and laugh derisively :-)
If you wanted to implement such a beast, you could use something like intDivEx in the following program (using the overflow variant):
#include <iostream>
#include <stdexcept>
// Integer division/remainder, catching divide by zero.
inline int intDivEx (int numerator, int denominator) {
if (denominator == 0)
throw std::overflow_error("Divide by zero exception");
return numerator / denominator;
}
inline int intModEx (int numerator, int denominator) {
if (denominator == 0)
throw std::overflow_error("Divide by zero exception");
return numerator % denominator;
}
int main (void) {
int i = 42;
try { i = intDivEx (10, 0); }
catch (std::overflow_error &e) {
std::cout << e.what() << " -> ";
}
std::cout << i << std::endl;
try { i = intDivEx (10, 2); }
catch (std::overflow_error &e) {
std::cout << e.what() << " -> ";
}
std::cout << i << std::endl;
return 0;
}
This outputs:
Divide by zero exception -> 42
5
and you can see it throws and catches the exception (leaving the return variable untouched) for the divide by zero case.
The % equivalent is almost exactly the same:
Updated with comments from ExcessPhase
GCC (at least version 4.8) will let you emulate this behaviour:
#include <signal.h>
#include <memory>
#include <iostream>
int main() {
std::shared_ptr<void(int)> handler(
signal(SIGFPE, [](int signum) {throw std::logic_error("FPE"); }),
[](__sighandler_t f) { signal(SIGFPE, f); });
int i = 0;
std::cin >> i; // what if someone enters zero?
try {
i = 5/i;
}
catch (std::logic_error e) {
std::cerr << e.what();
}
}
This sets up a new signal handler which throws an exception, and a shared_ptr to the old signal handler, with a custom 'deletion' function that restores the old handler when it goes out of scope.
You need to compile with at least these options:
g++ -c Foo.cc -o Foo.o -fnon-call-exceptions -std=c++11
Visual C++ will also let you do something similar:
#include <eh.h>
#include <memory>
int main() {
std::shared_ptr<void(unsigned, EXCEPTION_POINTERS*)> handler(
_set_se_translator([](unsigned u, EXCEPTION_POINTERS* p) {
switch(u) {
case FLT_DIVIDE_BY_ZERO:
case INT_DIVIDE_BY_ZERO:
throw std::logic_error("Divide by zero");
break;
...
default:
throw std::logic_error("SEH exception");
}
}),
[](_se_translator_function f) { _set_se_translator(f); });
int i = 0;
try {
i = 5 / i;
} catch(std::logic_error e) {
std::cerr << e.what();
}
}
And of course you can skip all the C++11-ishness of this and put them in a traditional RAII-managing struct.
As far as I know C++ specifications does not mention anything about divide by zero exeption. I believe you need to do it yourself...
Stroustrup says, in "The Design and Evolution of C++" (Addison Wesley, 1994), "low-level events, such as arithmetic overflows and divide by zero, are assumed to be handled by a dedicated lower-level mechanism rather than by exceptions. This enables C++ to match the behaviour of other languages when it comes to arithmetic. It also avoids the problems that occur on heavily pipelined architectures where events such as divide by zero are asynchronous."`
You need to throw the exception manually using throw keyword.
Example:
#include <iostream>
using namespace std;
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
int main ()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
You should check if i = 0 and not divide then.
(Optionally after checking it you can throw an exception and handle it later).
More info at: http://www.cprogramming.com/tutorial/exceptions.html
setjmp + longjmp
https://stackoverflow.com/a/25601100/895245 mentioned the possibility or throwing a C++ exception from a signal handler, but Throwing an exception from within a signal handler mentions several caveats of that, so I would be very careful.
As another potentially dangerous possibility, you can also try to use the older C setjmp + longjmp mechanism as shown at: C handle signal SIGFPE and continue execution
main.cpp
#include <csetjmp>
#include <csignal>
#include <cstring>
#include <iostream>
jmp_buf fpe;
void handler(int signum) {
longjmp(fpe, 1);
}
int main() {
volatile int i, j;
for(i = 0; i < 10; i++) {
struct sigaction act;
struct sigaction oldact;
memset(&act, 0, sizeof(act));
act.sa_handler = handler;
act.sa_flags = SA_NODEFER | SA_NOMASK;
sigaction(SIGFPE, &act, &oldact);
if (0 == setjmp(fpe)) {
std::cout << "before divide" << std::endl;
j = i / 0;
sigaction(SIGFPE, &oldact, &act);
} else {
std::cout << "after longjmp" << std::endl;
sigaction(SIGFPE, &oldact, &act);
}
}
return 0;
}
Compile and run:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
Output:
i = 0
before divide
after longjmp
i = 1
before divide
after longjmp
i = 2
before divide
after longjmp
man longjmp says that you can longjmp from signal handlers, but with a few caveats:
POSIX.1-2008 Technical Corrigendum 2 adds longjmp() and siglongjmp() to the list of async-signal-safe functions. However, the standard recommends avoiding the use of these functions from signal handlers and goes on to point
out that if these functions are called from a signal handler that interrupted a call to a non-async-signal-safe function (or some equivalent, such as the steps equivalent to exit(3) that occur upon a return from the initial
call to main()), the behavior is undefined if the program subsequently makes a call to a non-async-signal-safe function. The only way of avoiding undefined behavior is to ensure one of the following:
After long jumping from the signal handler, the program does not call any non-async-signal-safe functions and does not return from the initial call to main().
Any signal whose handler performs a long jump must be blocked during every call to a non-async-signal-safe function and no non-async-signal-safe functions are called after returning from the initial call to main().
See also: Longjmp out of signal handler?
However Throwing an exception from within a signal handler mentions that this has further dangers with C++:
setjmp and longjmp aren't compatible with exceptions and RAII (ctors/dtors), though. :( You'll probably get resource leaks with this.
so you would have to be very very careful with that as well.
I guess the moral is that signal handlers are hard, and you should avoid them as much as possible unless you know exactly what you are doing.
Detect floating point zero division
It is also possible to detect floating point division by zero with a glibc call to:
#include <cfenv>
feenableexcept(FE_INVALID);
as shown at: What is the difference between quiet NaN and signaling NaN?
This makes it raises SIGFPE as well like the integer division by zero instead of just silently qnan and setting flags.
What about this one? Tested with Clang, GCC throws SIGILL.
#include <iostream>
#include <cassert>
int main()
{
unsigned int x = 42;
unsigned int y = x;
y -= x;
x /= y;
std::cout << x << " != "<< *(&x) << std::endl;
assert (*(&x) == x);
}
do i need to throw an exception or does the computer automatically throws one at runtime?
Either you need to throw the exception yourself and catch it. e.g.
try {
//...
throw int();
}
catch(int i) { }
Or catch the exception which is thrown by your code.
try {
int *p = new int();
}
catch (std::bad_alloc e) {
cerr << e.what();
}
In your case, I am not sure if is there any standard exception meant for divide by zero. If there is no such exception then you can use,
catch(...) { // catch 'any' exception
}
You can just do assert(2 * i != i) which will throw an assert. You can write your own exception class if you need something fancier.
I'm creating a library. I want to make a fixed-length string class.
#include <string>
#include <iostream>
#define OK 0
#define TOO_LONG 1
#define UNALLOWED_CHARACTERS 2
struct MyString {
MyString(int l)
: m_length(l) { }
struct exception {
exception(int t, MyString *p)
: type(t), ptr(p) { }
int type;
MyString *ptr;
};
int set(const std::string& name);
void set2(const std::string& name) throw(exception);
std::string m_str;
int m_length;
};
int MyString::set(const std::string& s)
{
if(s.size() > 64) {
return TOO_LONG;
} else if(s.find('~') != std::string::npos) {
return UNALLOWED_CHARACTERS;
} else {
m_str = s;
return OK;
}
}
void MyString::set2(const std::string& s) throw(exception)
{
if(s.size() > m_length) {
throw exception(TOO_LONG, this);
} else if(s.find('~') != std::string::npos) {
throw exception(UNALLOWED_CHARACTERS, this);
} else {
m_str = s;
}
}
int main()
{
using namespace std;
//OPTION 1
{
MyString s1(10);
MyString s2(10);
int code;
code = s1.set("abcdefghijX");
switch(code) {
case TOO_LONG:
//handle <--
break;
case UNALLOWED_CHARACTERS:
//handle
break;
default:
//ok!
break;
}
code = s2.set("abcdefghi~");
switch(code) {
case TOO_LONG:
//handle
break;
case UNALLOWED_CHARACTERS:
//handle <--
break;
default:
//ok!
break;
}
}
//OPTION 2
{
MyString s1(10);
MyString s2(10);
try {
s1.set2("abcdefghijX");
s2.set2("abcdefghi~");
} catch(MyString::exception &e) {
cerr << "MyString::exception: ";
auto p = e.ptr;
if(p == &s1) cerr << "s1 ";
else if(p == &s2) cerr << "s2 ";
switch(e.type) {
case TOO_LONG: cerr << "too long"; break;
case UNALLOWED_CHARACTERS: cerr << "unallowed characters"; break;
}
cerr << endl;
}
}
}
I don't know which version of MyString::set() I should use. What is the convention in such cases? I used STL in this example for demonstration purposes.
It is a good idea to mimic the behavior of the standard library functions unless one has a specific reason not to. BTW, since tr1, STL has a fixed-length string class built in. Lets see what it does. The only example implementation I have handy is Visual C++ 2010.
std::tr1::array<int,5> arry;
arry[10] = 42; // Oopsie. There is no element 10.
When compiled and run as the "Debug" version, I get an assert failure. When compiled for "Release" the offensive statement quietly does ... NOTHING. It is optimized right out of existence. Okay, maybe that is not always what one would want. Forget what I said about mimicking the STL, or at least Microsoft's implementation. Train of consciousness continues...
I think it is fair to say that if the program tries to set an out of range cell, that is a logic error in the program. In mission-critical software it might be a good idea to have code in place to deal with a situation like that and recover from it, while trying like heck to make sure it can never, never happen.
So the answer is, throw an exception of type std::out_of_range.
So there.
In general in C++ it's recommended to use exceptions to indicate errors unrecoverable in the current context. But it depends on purpose. You may want to compile your library in an embedded environment using no exceptions (for sake of efficiency), then you have to go with return codes.
Its easy to wrap an API using return codes to one that uses exceptions, but no way vice versa.
EDIT:
Some more reasoning why it may make sense not to use exception handling:
Exception handling usually introduces additional information about try/catch blocks necessary to be placed in the call stack + some performance penalty to build and check these informations.
See also: performance of C++0x exceptions
EDIT: After even more code modification, the error is still there, modified code shown:
KeyDown():
const int input_bit_num = 0x8000;
char keys[256];
bool KeyDown(int key)
{
return (keys[key] & input_bit_num) != 0;
}
PollKeyboard():
LPDIRECTINPUTDEVICE8 di_keyboard;
void PollKeyboard()
{
long result = di_keyboard->GetDeviceState(sizeof(keys), (LPVOID)&keys);
char para[16];
itoa(result, para, 17);
if(result != DI_OK) MessageBox(NULL, para, "ERROR", MB_OK);
}
When I try to put MessageBox within a KeyDown() if statement (as seen below in the game loop), the MessageBox simply coninues to appear even if I stop pressing the key, ie: I press , the "Would you like to quit?" message box appears, I say no, It disappears and then instantly reappears, as if I were still holding the key.
This is my loop:
void GameRun(HWND hWnd) //called once every frame
{
PollKeyboard();
if(GetTickCount - start >= 30)
{
if(KeyDown(DIK_LEFT))
MoveLeft();
if(KeyDown(DIK_RIGHT))
MoveRight();
}
if(d3ddev->BeginScene())
{
//rendering
}
if(KeyDown(DIK_ESCAPE))
{
//any MessageBox()
int result = MessageBox(hWnd, "I'm causing so much trouble!", "IMMORTAL", MB_YESNOCANCEL);
if(result == IDYES)
//end
}
}
EDIT: The catch in PollKeyboard() displays the sequence 53gd6bcc, I could not, however, find the error code it corresponds to.
EDIT: After another test, I saw that even if the MessageBox is not within a KeyDown() if statement, the glitch still occurs.
EDIT: After a bit more testing, it appears that MessageBox itself is causing the glitch.
Because the sample code works, something else in your program is causing the bug. Try moving bits of the code below into your own until it works, then you will know which section of code was culprit.
Sample Code
Alright, huge code block coming up. This code works correctly for me. (Escape, along with all other keys successfully activate and deactivate). It's large, commented, and explains things fairly well. Try this, if it works, we'll examine other parts of your program, if not, I can only leave you with "Good luck", and take what you want:
// DirectInput
#define DIRECTINPUT_VERSION 0x0800
#include<dinput.h>
// Standard stuff
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <string>
// Link from code, MSVC specific, could be done in project settings
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")
// Utility lexical_cast, use Boost if possible.
// Simple replacement, converts a stream-able `T`
// to a string
template <typename T>
const std::string lexical_cast(const T& pValue)
{
std::stringstream ss;
ss << pValue;
return ss.str();
}
// Utility function + macro to execute DirectX code with exceptions.
// Kinda ugly, but helpful for us.
void check_error(HRESULT pResult, const std::string& pFuncName)
{
// DI_OK == S_OK, but S_OK is more general, so we'll use that
if (pResult != S_OK)
{
throw std::runtime_error("Error executing: " + pFuncName +
"! Returned: " + lexical_cast(pResult));
}
}
// Macro, makes calling the function easier. It is wrapped in
// an `if` statement for reasons outlined in:
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.5
#define CHECK_ERROR(x) if (true) { check_error(x, #x); } else (void)0
// The above gives the warning:
// "warning C4127: conditional expression is constant", disable below:
#pragma warning(disable: 4127)
// Manages input
class input_manager
{
public:
// Constants
static const int NumberKeys = 256;
// Creation
input_manager(void)
{
// Create input and keyboard (like I said, ugly macro, but helpful :] )
CHECK_ERROR(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, reinterpret_cast<void**>(&_input), 0));
CHECK_ERROR(_input->CreateDevice(GUID_SysKeyboard, &_keyboard, 0));
CHECK_ERROR(_keyboard->SetDataFormat(&c_dfDIKeyboard));
CHECK_ERROR(_keyboard->Acquire());
}
~input_manager(void)
{
// Free resources. Note: Many programmers
// unnecessarily wrap this stuff in
// `if (_keyboard !=0)`, and then
// `_keyboard = 0`. This is completely unnecessary,
// because destructors are only run one time.
// Also, I can assume they are valid, because if they
// weren't, we wouldn't be here (an exception would have
// been thrown)
_keyboard->Unacquire();
_keyboard->Release();
_input->Release();
// Also, if we wrapped this into a nice RAII class, we wouldn't
// be forced to write a destructor, but this is outside the scope.
// Feel free to ask how; additionally, since we're on the topic, if you'd
// like more tips handling input (I've written PLENTY of input managers)
// I'm free for asking about things like testing for triggers rather than pressed
// ("was it pressed, regardless if it's being held now" versus
// "is it being pressed"), etc.
}
// Operations
void update(void)
{
CHECK_ERROR(_keyboard->GetDeviceState(NumberKeys, reinterpret_cast<void*>(&_keys)));
}
// Query
bool key_pressed(int pKey) const
{
return test_key(pKey);
}
// Might wrap into an operator[] for convenience.
private:
// Constants
static const int PressMask = 0x80;
// Sorry for the confusion, but indeed, with
// `char`s the mask is simply 0x80.
// Utility
bool test_key(int pKey) const
{
return (_keys[pKey] & PressMask) != 0;
}
// Members
LPDIRECTINPUT8 _input;
LPDIRECTINPUTDEVICE8 _keyboard;
char _keys[NumberKeys];
};
void test_keys(const input_manager& input)
{
bool anyPressed = false;
for (unsigned i = 0; i < input_manager::NumberKeys; ++i)
{
if (input.key_pressed(i))
{
std::cout << "Pressing: " << i << std::endl;
anyPressed = true;
}
}
if (!anyPressed)
{
std::cout << "No keys pressed." << std::endl;
}
}
void execute(void)
{
input_manager input;
std::cout << "Press Q to quit." << std::endl;
bool running = true;
while (running)
{
input.update();
if (input.key_pressed(DIK_Q))
{
running = false;
}
test_keys(input);
Sleep(0); // give some processor time
}
}
int main(void)
{
// Place real code in an execute function, so main
// is clean and ready to catch exceptions:
try
{
execute();
}
catch (const std::exception& e)
{
// Error!
std::cerr << "Unhandled exception:" << e.what() << std::endl;
}
}
Old suggestion:
Try catching the return value from GetDeviceState:
HRESULT result = // v Prefer C++-style casts
di_keyboard->GetDeviceState(sizeof(keys), reinterpret_cast<void*>(&keys);
if (result != DI_OK)
{
// uh-oh
std::cout << result << std::endl;
}
Compare it against the table here.
Old Semi-Answer:
Shortly after editing in the code in the Extra Stuff section, I realized the error, sorry I didn't catch it earlier. You're testing the wrong bit :)
Observe:
// v HERE! Should be 0x8000, not 0x80.
return (GetAsyncKeyState(pKeyCode) & 0x8000) != 0;
Try that:
int KeyDown(int key)
{
return (keys[key] & 0x8000);
}
Also, this should be moved into a constant to avoid magic numbers:
// somewhere, probably in the private section of the class or in a detail namespace:
static const int PushedMask = 0x8000;
// code reads better:
int KeyDown(int key)
{
return (keys[key] & PushedMask);
}
Lastly, in C++ you have a bool type, so take advantage of it!
// v here
bool KeyDown(int key)
{
return (keys[key] & PushedMask);
}
I know Visual Studio will warn about this conversion from int to bool, so you can get rid of it while also making your intents clearer:
bool KeyDown(int key)
{
return (keys[key] & PushedMask) != 0; // or == 1, your choice
}
Extra Stuff:
Try the following code:
#include <iostream>
#include <windows.h>
bool key_pressed(int pKeyCode)
{
return (GetAsyncKeyState(pKeyCode) & 0x8000) != 0;
}
void test_keys(void)
{
for (unsigned i = 0; i < 255; ++i)
{
if (key_pressed(i))
{
std::cout << "Pressing: " << i << std::endl;
}
}
}
int main(void)
{
bool running = true;
while (running)
{
if (key_pressed(VK_ESCAPE))
{
running = false;
}
test_keys();
Sleep(0);
}
}
This works for me (responds to all keys, quits on escape). Minimal test case for GetAsyncKeyState. If this does not work, please add OS, Keyboard, etc, in your comment.
If you create a MessageBox(Null,...) you won't have any control over the window after it's creation. IE, the window won't disappear when you depress the key.
As for why it keeps on appearing, seems to have something to do with this:
const int input_bit_num = 0x8000;
char keys[256];
bool KeyDown(int key)
{
return (keys[key] & input_bit_num) != 0;
}
keys consits of 1 byte long characters, while input_bit_num is a 2 byte value. While I don't honestly know which bit it is that you're looking for (0xff - 0x00 is the domain of 1 byte).
Honestly, I'm surprised that your code runs, unless the & operation is carrying over into keys[key-1] in which case any KeyDown is undefined, and KeyDown(...) when key is 0 is particularly dangerous.