C++ catch error and exit the function - c++

I use try{} catch(){} to handle errors in a function which return a template type.
T get (int iOffset) const
{
try {
checkIndex(iOffset);
}
catch (char const* msg) {
std::cout << msg << std::endl;
}
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
float a = m_ptBuff[index];
return a;
}
The function would first call checkIndex to check whether the input is out of range and throw an error if so.
However, I don't want the outside get return any value if checkIndex throws an error, because the returned value may be used by other functions or printed out incorrectly. If I put a return in the catch block, I don't know what to return since it's a template. If I don't, the codes following the catch block will still get executed and therefore return a value.
Is there any way to do that? I'm new to C++ and wondering how people usually do the error handling in this condition? THanks!

However, I don't want the outside get return any value if checkIndex throws an error, because the returned value may be used by other functions or printed out incorrectly.
You can always re-throw the exception after logging
T get (int iOffset) const
{
try {
checkIndex(iOffset);
}
catch (char const* msg) {
std::cout << msg << std::endl;
throw; // Just re-throw the exception
}
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
float a = m_ptBuff[index];
return a;
}

You can also use optional for this situation. One of idea of this construct was to indicate that value cannot be set correctly because of some mistakes.
std::optional< T > get (int iOffset ) const
{
try {
checkIndex(iOffset);
}
catch (char const* msg) {
std::cout << msg << std::endl;
return std::optional< T >();
}
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
float a = m_ptBuff[index];
return return std::optional< T >( a );
}
Using of such function can look like this:
auto result = get( someOffset );
if( result )
{
// correct, processing result
}

One of the easiest way is first to decide: What exactly should your get() return if it cannot return the 'proper' value?
In many cases it is just 0, or -1, or some other special value.
And then the code become very simple:
T get (int iOffset) const
{
T a;
try {
checkIndex(iOffset);
int index = (m_iReadIdx + iOffset) % m_iBuffLength;
a = m_ptBuff[index];
}
catch (char const* msg) {
a = special_value_for_errors;
std::cout << msg << std::endl;
}
return a;
}

Related

Handling an error condition in the compare function of std::qsort

I am trying to figure out a way for qsort to throw an exception or indicate an error condition if the compare function finds that the elements are, for some reason, invalid for sorting.
For example, in this compare function, I need to indicate an error condition that my sorting is invalid if the return value of some_function is 5.
How should I modify my compare function?
int compare (const void * a, const void * b)
{
int ret1 = some_func(a);
int ret2 = some_func(b):
return ( ret1 - ret2 );
}
I am dealing with a legacy code base so I'm not in the position to use std::sort and due to the nature of the implementation calling some_func before hand might also involve huge amount of changes so I'm looking to understand if a workaround is possible.
C++ allows you to throw whatever you need, not only exceptions but also other types, you could do something like throw an int if it suits your purposes and catch where you call the function with a try-catch block.
For what you need I think you can use STL exception library:
Demostrative example:
#include <iostream>
#include <exception>
int count = 0;
int compare(const void *a, const void *b)
{
int ret1 = *(int*)a > *(int*)b;
if (++count == 5) //throws exception when count reaches 5
throw std::invalid_argument("Argument is not sortable");
//you could throw count by simply using throw count
return ret1;
}
int main()
{
int x[]{2,1,3,5,6,1,7,2,5,3};
try
{
//will sort until exception is thrown
qsort(x, sizeof x / sizeof *x, sizeof(int), compare);
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl; //print exception in the console
//handle the exception here
//if you were to throw count you could cach it with
//catch (int &e)
}
//note that the values were sorted until the exception was thrown
for (int i = 0; i < sizeof x / sizeof *x; i++){
std::cout << x[i] << " ";
}
}
Output:
Argument is not sortable
1 2 3 5 6 1 7 2 5 3
^
sorting
stopped
here
Throwing an exception is potentially expensive, so you probably want to return an error condition. However, doing either approach inside the compare function is needlessly expensive in this case, since you would be doing the check multiple times for every element. Instead, you could just check for the error condition before calling qsort which is much more efficient:
auto ok = std::none_of(/* range */, /* predicate */);
if (ok)
std::qsort(/* ... */)
else
// report error

What is the return value of the given function on encountering an exception?

checkUsername() checks the username's length, and returns true when length is greater than or equal to 5. Otherwise it returns false.
The function checkUsername() should return false on BadLengthException(), but it doesn't seem to appear as none of the code within checkUsername() and BadLengthException::what() returns false. But still the program is working fine when it encounters a username of length less than 5. What's going on here? How is the return value passed false?
class BadLengthException: public exception{
public:
int n;
BadLengthException(int x) { n=x; };
virtual int what() throw() {
return n;
}
};
/*
This function checks the username's length,
and returns true when length is greater than or equal to 5.
Otherwise it returns false.
*/
bool checkUsername(string username) {
bool isValid = true;
int n = username.length();
if(n < 5) {
throw BadLengthException(n); //the problem
}
for(int i = 0; i < n-1; i++) {
if(username[i] == 'w' && username[i+1] == 'w') {
isValid = false;
}
}
return isValid;
}
int main() {
int T; cin >> T;
while(T--) {
string username;
cin >> username;
try {
bool isValid = checkUsername(username);
if(isValid) {
cout << "Valid" << '\n';
} else {
cout << "Invalid" << '\n';
}
} catch (BadLengthException e) {
cout << "Too short: " << e.what() << '\n';
}
}
return 0;
}
A function can either return a value or throw an exception, it can't do both, they're mutually exclusive. If it successfully returns a value that means the code didn't throw an exception, and if an exception was thrown then it means it didn't make it to the point of returning a value.
Further to that, capturing the return value is also interrupted, the code jumps right to the catch block you've defined. It's like a hard goto in concept, if you ignore things like automatic object destruction and finally type implementations which will happen in the process of an exception bubbling up.
When the exception is thrown in checkUsername(), it stops processing in that function and returns to the calling function which is main(). Because the call was made in a try block the exception is handled by the catch block.
The if() statement is completely ignored and the catch doesn't care about what happened in that function and just prints "Too short: "

LuaPlus: Register function with paramers and one return value?

I don't really understand the system. Using .RegisterDirect("myFunc",myFunc) I can register a function that can't take parameters, but therefore can return a value.
Using .Register("myFunc",myFunc) I can register a function that can take parameters, but therefore can't return any values.
I literally spent days on this issue now and I just can't figure it out. I would really appreciate it if someone would take a look at this.
Here is the documentation. Here is a quick example of how Register and RegisterDirect. Let's say I wanted the Print function to always return the string "hello". How would I do that?
#include "stdafx.hpp"
int Print(LuaPlus::LuaState* pState) {
int top = pState->GetTop();
std::stringstream output;
for( int i = 1; i <= top; ++i ) {
output << pState->CheckString(i) << std::endl;
}
std::cout << output.str();
return 0; // We don't return any values to the script
}
int Get2222() {
return 2222;
}
int main() {
LuaPlus::LuaState* pState = LuaPlus::LuaState::Create( true );
LuaPlus::LuaObject globals = pState->GetGlobals();
globals.Register("Print",Print);
globals.RegisterDirect("Get2222",Get2222);
char pPath[ MAX_PATH ];
GetCurrentDirectory(MAX_PATH,pPath);
strcat_s(pPath,MAX_PATH,"\\test.lua");
if( pState->DoFile(pPath) ) {
// An error occured
if( pState->GetTop() == 1 )
std::cout << "An error occured: " << pState->CheckString(1) << std::endl;
}
LuaPlus::LuaState::Destroy( pState );
pState = nullptr;
getchar();
return 0;
}
Afaik I would have to push the value on the stack and return 1 to indicate that there is something on the stack. But that didn't seem work. I tried to add this to the function to return the number 4:
pState->PushInteger(4);
return 1;
I really hope you can help me out here.

exceptions and return statements in c++

I am new in c++ programming and i am trying to understand exceptions in c++. I made a simple model situation that shows things, which I don't understand(I hope, I wont mess up code too much). I made 2 basic classes with few methods(classes CPerson are basically linked list). My answer is how to stop current task with an exception. I am able to call an exception, but task continues and makes some mess in program.
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
class CPerson{
public:
CPerson(){
p_next_person = NULL;
}
CPerson* p_next_person; // pointer to next person in linked list
int Postcode(); // returns postcode of person
friend ostream& operator<<(ostream& stream, const CPerson& pers){
cout << pers.ID << pers.postcode;
return stream;
}
char* ID;
int postcode;
};
//---------------------------------------------------------------
class CPeople{
public:
CPeople(){
first_person = NULL;
}
CPerson Person( const char* personID); // finds person by ID and returns it
bool NewPerson( const char* personID, int person_postcode); // add new person
CPerson* first_person ; // start of linked list
};
//-----------------------------------------------------------------
int CPerson::Postcode(){
return postcode;
}
//-----------------------------------------------------------------
CPerson CPeople::Person( const char* personID){
CPerson* now;
now = first_person;
while(now != NULL){
if(strcmp(now->ID,personID)==0){
break;
}
now = now->p_next_person;
}
// our person is in now (or now is NULL - if person wasn't found).
try{
if(now == NULL ){
throw 0;
// I need to stop code here
}else return *now;
}
catch (int e)
{
cout << "bla bla " << e << '\n';
}
}
//----------------------------------------------------------
int main(){
CPeople people;
int i = 0;
people.NewPerson( "JAck", 100 );
people.NewPerson( "Josh", 100 );
// Bob is not in people right now.
i = people.Person("BOB").Postcode();
cout << i;
// gives exception, which is nice. but it also changes i to some nonsence .. how do I fix it ?
cout << people.Person ( "BOB" );
// gives exception, which is nice. but also gives segmentation fault. how do I fix it ?
}
You have got the try block around 'throw. The try block should be around where you called the function and it should be caught with a catch. Thus your function will change to:
CPerson CPeople::Person( const char* personID){
CPerson* now;
now = first_person;
while(now != NULL){
if(strcmp(now->ID,personID)==0){
break;
}
now = now->p_next_person;
}
// our person is in now (or now is NULL - if person wasn't found).
if (now == NULL ){
throw 0;
// I need to stop code here
}
else return *now;
}
and main will look like:
int main(){
try {
CPeople people;
int i = 0;
people.NewPerson( "JAck", 100 );
people.NewPerson( "Josh", 100 );
// Bob is not in people right now.
i = people.Person("BOB").Postcode();
cout << i;
// gives exception, which is nice. but it also changes i to some nonsence .. how do I fix it ?
cout << people.Person ( "BOB" );
// gives exception, which is nice. but also gives segmentation fault. how do I fix it ?
}
catch (int e)
{
cout << "bla bla " << e << '\n';
}
}
Notice that once a catch is encountered, the following statement after the catch will be executed. That is why you should have catch out of the function definition.
Code like this
try{
if( now == NULL ){
throw 0;
// I need to stop code here
} else return *now;
} catch (int e) {
cout << "bla bla " << e << '\n';
}
entirely misses the point. Continuing execution with a shrug ("bla bla") as if nothing had happened isn't possible. Either you make sure that all contingencies are met in the catch, or you should catch the exception at a higher level. Here: there is no definition of the function's return value, which causes trouble up there where you call CPeople::Person.
You can surround these calls with a try - catch; omit them in the function and just throw.
Don't throw 0. Use an object capable of holding some information. Throw by value, catch by reference.

Error checking on many function calls

Sometimes when I am programming in C++/C I end up calling the same function multiple times and I was wondering what is the most efficient way to check for errors for all of those calls? Using if else statements take up a lot of code and look ugly. I have come up with my own way of checking for errors, perhaps there is a better way that I should use.
int errs[5] = {0};
errs[0] = functiona(...);
errs[1] = functiona(...);
...
errs[5] = functiona(...);
for (int i = 0; i < 5; i++)
{
if (err[i] == 0)
MAYDAY!_wehaveanerror();
}
Note: I understand that using try and catch might be better for C++ as it would solve this problem by throwing an exception on the first error, but the problem with that is that it is not compatible with a lot of functions that return error codes such as the Windows API. Thanks!
You could write some pseudo-C++ like this:
struct my_exception : public std::exception {
my_exception(int); /* ... */ };
int main()
{
try
{
int e;
if ((e = function()) != SUCCESS) { throw my_exception(e); }
if ((e = function()) != SUCCESS) { throw my_exception(e); }
if ((e = function()) != SUCCESS) { throw my_exception(e); }
}
catch (my_exception & e)
{
std::cerr << "Something went wrong: " << e.what() << "\n";
}
}
If...IF the function has a chance to throw a different error you should also add a catch all.
struct my_exception : public std::exception {
my_exception(int); /* ... */ };
int main()
{
try
{
int e;
if ((e = function()) != SUCCESS) { throw my_exception(e); }
if ((e = function()) != SUCCESS) { throw my_exception(e); }
if ((e = function()) != SUCCESS) { throw my_exception(e); }
}
catch (my_exception & e)
{
std::cerr << "Something went wrong: " << e.what() << "\n";
}
catch (...)
{
//Error Checking
}
}
What about handling the checking in a function?
void my_function() {
if (!create_window())
throw Error("Failed to create window");
}
int main() {
try {
my_function();
} catch (const Error& e) {
cout << e.msg << endl;
} catch (...) {
cout << "Unknown exception caught\n"
}
return 0;
}
If you're calling the same function over and over again, the most succinct way might be to use a macro. I would suggest something like:
#define CHECKERROR(x) if(x == 0) wehaveanerror()
CHECKERROR(function(...));
CHECKERROR(function(...));
Obviously, this macro would be very specific to the particular function and error handler involved, so it may be prudent to undef it after those calls.
Doing it more old-school, but keeping w/ the original error response but responding as soon as an error occurs w/o looking ugly:
#define callcheck(r) if ((r)==0) MAYDAY!_wehaveanerror()
callcheck(functiona(...));
callcheck(functiona(...));
...