Can I make a #define and use it in a throw? - c++

Can I make something like this?
#define N_VALID "is not a valid ID"
...
throw N_valid;
...
catch(char *message){
fprintf(stderr,"%s",message);}

Yes, except that you are throwing a const char *, not a char *: https://ideone.com/UsnitG
#include <iostream>
using std::cout; using std::endl;
#define N_VALID "is not a valid ID"
void function_throws()
{
throw N_VALID;
}
int main()
{
try
{
function_throws();
}
catch(const char *message) // <= Note the const here!
{
cout << message << endl;
}
}
However, Joel is correct that you should avoid doing this. If you really want to use a macro here, try using it as an argument to a std::exception object: https://ideone.com/Dsx1RF
void function_throws()
{
throw invalid_argument(N_VALID);
}
int main()
{
try
{
function_throws();
}
catch(const invalid_argument& ex)
{
cout << "invalid_argument: " << ex.what() << endl;
}
}

Yes.
#define N_VALID "is not a valid ID"
throw N_VALID;
throw "is not a valid ID";
The bottom two lines above are literally identical in the eyes of the compiler, once pre-processing has completed.

This is legal but immoral. You should ALWAYS throw an object so that your clients can handle your errors individually, rather than having a giant if statement in one catch.

The #define directive works by replacing a tag with another tag in your code before the application is compiled. Thus, if you can do this:
throw "is not a valid ID";
you can do this:
throw N_VALID;

It should work. Remember, the pre-processsor runs before the compiler and will replace the N_VALID with "is not a valid ID"

Related

Do you need to know what exception is going to occur to handle them in C++?

<C++>In exception handling, do you need to know what exception and where an exception is going to occur? Can you make a code which will print and notify us that an exception occurred somewhere in the program. I mean I have a program in which I don't know if an exception will occur or not, if one was to occur, then it will print to notify us.
Exception handling is something you should design for, and in fact it works very well together with RAII (https://en.cppreference.com/w/cpp/language/raii).
(Notr On embedded platforms using exceptions, is not so popular because of some runtime overhead). What I personally like about exceptions is that it separates error handling from the normal program flow (there will be hardly any if then else checks when done right)
// Exception handling should be part of your overal design.And many standard library functions can throw exceptions, It is always up to you where you handle them.
#include <iostream>
#include <string>
#include <stdexcept>
int get_int_with_local_exception_handling()
{
do
{
try
{
std::cout << "Input an integer (local exception handling, enter a text for exception): ";
std::string input;
std::cin >> input;
// stoi is a function that can throw exceptions
// look at the documentation https://en.cppreference.com/w/cpp/string/basic_string/stol
// and look for exceptions.
//
int value = std::stoi(input);
// if input was ok, no exception was thrown so we can return the value to the client.
return value;
}
// catch by const reference, it avoids copies of the exception
// and makes sure you cannot change the content
catch (const std::invalid_argument& e)
{
// std::exceptions always have a what function with readable info
std::cout << "handling std::invalid_argument, " << e.what() << "\n";
}
catch (const std::out_of_range& e)
{
std::cout << "handling std::out_of_range, " << e.what() << "\n";
}
} while (true);
}
int get_int_no_exception_handling()
{
std::cout << "Input an integer (without exception handling, enter a text for exception): ";
std::string input;
std::cin >> input;
int value = std::stoi(input);
return value;
}
int main()
{
try
{
// this function shows you can handle exceptions locally
// to keep program running
auto value1 = get_int_with_local_exception_handling();
std::cout << "your for input was : " << value1 << "\n";
// this function shows that exceptions can be thrown without
// catching, but then the end up on the next exception handler
// on the stack, which in this case is the one in main
auto value2 = get_int_no_exception_handling();
std::cout << "your input was : " << value1 << "\n";
return 0;
}
catch (const std::exception& e)
{
std::cout << "Unhandled exception caught, program terminating : " << e.what() << "\n";
return -1;
}
catch (...)
{
std::cout << "Unknown, and unhandled exception caught, program terminating\n";
}
}
Yes and no.
No, because any exception thrown via throw some_exception; can be catched via catch(...).
Yes, because catch(...) is not very useful. You only know that there was an excpetion but not more.
Typically exceptions carry information on the cause that you want to use in the catch. Only as a last resort or when you need to make abolutely sure not to miss any excpetion you should use catch(...):
try {
might_throw_unknown_exceptions();
} catch(std::exception& err) {
std::cout << "there was a runtime error: " << err.what();
} catch(...) {
std::cout << "an unknown excpetion was thrown.";
}
The C++ standard library uses inheritance only sparingly. Exceptions is only place where it is used extensively: All standard exceptions inherit from std::exception and it is good practice to inherit also custom exceptions from it.

Variable scope strange behavior in C++

My program invokes methods that will set errno when a failure occurs, I throw errno like an exception and catch it:
try
{
if (-1 == truncate("/foo/bar.txt", 0))
{
throw errno;
}
}
catch (const int errno)
{
//log
}
Here I don't want to discuss the exception handling best practice topic. The truth is in the code above, catch block will not hit when the variable name in catch bracket is errno. This issue can be simplified to:
try
{
throw 1999;
}
catch (const int errno) //renaming "errno" to "e" works!!!
{
//unreachable code here
}
I know errno is a "special" name, but I thought C++ could handle same variable names defined in different scopes correctly.
//test.h
int my_number = 99;
//test.cpp
#include "test.h"
int main()
{
try
{
throw 1999;
}
catch(int my_number)
{
std::cout << "in catch: " << my_number << std::endl; //prints 1999
}
std::cout << my_number << std::endl; //prints 99
}
The program is compiled in GNU5.4(happens in both C++11 and C++14). Can anyone explain the strange behavior?
errno is a macro. So your exception handler contains some expanded tokens that most likely make very little sense. From the standard ([errno]):
The contents of the header are the same as the POSIX header
, except that errno shall be defined as a macro.

Why does it print out "abracadabra" and not "Timmy"?

This code throws an exception when I enter "Timmy" as the name. I'm really not sure of the mechanism but why does it print out "abracadabra" and not "Timmy". One thing I'm sure of though is that there is no magic going on here!
This is the short code
#include <iostream>
using namespace std;
#include <string>
#include <cstdlib>
string enterName();
void checkName(string);
int main()
{
string someName = "abracadabra";
try {
someName = enterName();
}
catch(const char* error) {
cout << "main function says: "<<error <<endl;
}
cout << "Name: "<<someName<<endl;
return 0;
}
string enterName()
{
string s;
cout<<"Enter a name: ";
cin >> s;
cout<<endl;
try {
checkName(s);
}
catch(const char* err) {
cout << "middle man says: "<<err <<endl;
throw "rtetfrer";
}
return s;
}
void checkName(string name)
{
if (name == "Timmy")
throw "Help, Timmy's been kidnapped by a giant squid!";
}
You are throwing an exception, so the function never returns:
void checkName(string name)
{
if (name == "Timmy")
//This throws an exception, so the function exits immediately
throw "Help, Timmy's been kidnapped by a giant squid!";
}
That exception is caught here:
try {
checkName(s);
}
catch(const char* err) {
//This will be the exception that timmy is caught
cout << "middle man says: "<<err <<endl;
//This will throw an exception and immediately exit the function
throw "rtetfrer";
}
//This will never be called
return s;
And the new exception will be caught here:
catch(const char* error) {
cout << "main function says: "<<error <<endl;
}
But since checkName never returned a value, somename will still be magic
enterName(); throws an exception before the assignment to someName is made. Hence someName retains its original value.
(In a little more detail: enterName() calls checkName(). checkName() throws an exception since name is "Timmy". enterName() throws "rtetfrer". Why not verify with your debugger?)
In order to assign a value to someName, c++ must first evaluate the expression on the left side. That is the result of the function enterName. Now during the execution of this function an exception is thrown. When this happens the execution jumps right to the catch clause(skipping the return clause of the function and then the assignment of someName to this return value), thus you never assign a different value to someName.
Use a debugger to follow the execution flow in an easier manner.

The sample code provided returns a random number, even after throwing an exception (code provided)

I have a sample code to modify and throw exception handling. The problem is even after I threw an exception, the code still returns a random 0. I have spent some time trying to figure out why I still have a 0 returned but I could not find the answer. Does anyone have an idea why the code behaves like this?
#include <stdexcept>
#include <iostream>
#include <string>
using namespace std;
struct myException_Product_Not_Found : exception
{
virtual const char* what() const throw() {
return "Product not found";
}
} myExcept_Prod_Not_Found;
int getProductID(int ids[], string names[], int numProducts, string target) {
for (int i=0; i<numProducts; i++) {
if(names[i] == target)
return ids[i];
}
try {
throw myExcept_Prod_Not_Found;
}
catch (exception& e) {
cout<<e.what()<<endl;
}
}
// Sample code to test the getProductID function
int main() {
int productIds[] = {4,5,8,10,13};
string products[] = {"computer","flash drive","mouse","printer","camera"};
cout << getProductID(productIds, products, 5, "computer") << endl;
cout << getProductID(productIds, products, 5, "laptop") << endl;
cout << getProductID(productIds, products, 5, "printer") << endl;
return 0;
}
getProductID doesn't throw an exception. You catch the exception you do throw before getProductID has a chance to throw it. As such, you return ... well, nothing. The functions ends without you calling return.
If you had turned on your compiler's warnings* (as should should be doing), the compiler should warn with a message like control reaches end of non-void function. g++ appears to return zero in this instance, but returning zero is probably undefined behaviour.
If you want a function to throw an exception, don't catch the exception you've thrown inside of the function. Move the catch to the outside.
int getProductID(...) {
...
throw myExcept_Prod_Not_Found;
}
string product = "computer";
try {
cout << getProductID(productIds, products, 5, product) << endl;
} catch (exception& e) {
cout << "Can't find product id for " << product << ": " << e.what() << endl;
}
* — To turn on warnings in g++, -Wall is a good starting point. #Tomalak Geret'kal suggests -Wall -Wextra -std=c++98 -pedantic or -Wall -Wextra -std=c++0x -pedantic.
try {
throw myExcept_Prod_Not_Found;
}
catch (exception& e) {
cout<<e.what()<<endl;
}
Here you're throwing an exception and then immediately catching it. The exception message is output to console and then execution of your function continues as normal... except you have no value to return.
So, the result of that function call is unspecified, and you're seeing some arbitrary rubbish from memory as well as invoking undefined behaviour.
Instead, just let the exception propogate right up the callstack by not catching it: it'll lead your program to terminate (possibly without actually unrolling, incidentally):
throw myExcept_Prod_Not_Found;

c++ design question try catch

I have the following code in which dbh constructor may throw exception. The question I have is, dbh is declared inside try block. Will it be available after the catch? If yes, are there any other exceptions where the scope resolution is different than {} ? If not, what is the best design alternative?
status func(const char* field, char** value)
{
try {
dbhandler<recType> dbh(("dbName"),("table"));
}
catch (std::runtime_error &e) {
LOG_ERR << e.what() << endl ;
return false;
}
catch (...) {
LOG_ERR << "Unknown exception" << endl ;
return false;
}
rc = dbh.start("key",field, val);
return rc;
}
Will it be available after the catch?
No. It will be destroyed at the end of the block in which it is declared, just like any other local variable.
try {
dbhandler<recType> dbh(("dbName"),("table"));
} // dbh.~dbhandler<recType>() is called to destroy dbh
What is the best design alternative?
Declare dbh outside of the try block or move all the code that uses it into the try block. Which one makes the most sense depends on your specific use case.
On a somewhat related note, if you catch (...), you should either rethrow the exception or terminate the application: you have no idea what exception is being handled and in general you have no idea whether it is safe to continue executing.
According to your function code, it makes much sense to write it like that:
status func(const char* field, char** value)
{
try {
dbhandler<recType> dbh(("dbName"),("table"));
status rc = dbh.start("key",field, val);
return rc;
}
catch (std::runtime_error &e) {
LOG_ERR << e.what() << endl ;
return false;
}
catch (...) {
LOG_ERR << "Unknown exception" << endl ;
return false;
}
}