Why does this basic Try-Catch fail to catch [duplicate] - c++

This question already has answers here:
Why doesn't 'd /= d' throw a division by zero exception when d == 0?
(5 answers)
Closed 1 year ago.
I am learning about try-catch constructs in C++ and I have the following example that appears to fail to execute the code inside either of the catches. I have spent the past few hours trying to find the bug/issue without luck.
I am wondering if there is an issue with g++ on my machine -- I am using mingw's g++ and Windows 10.
#include <iostream>
#include <stdexcept>
int main(){
try {
std::cout << "Start of Try-Catch\n";
int a = 13;
int b = 0;
int p = a/b;
std::cout << "printing p: " << p << std::endl;
p = 43;
std::cout << "Passed the div by zero issue\n";
} catch (std::runtime_error& e){
std::cout << "runtime error: " << e.what() << '\n';
return 2;
} catch (std::exception& e){
std::cout << "other error: " << e.what() << '\n';
return 3;
} catch (...) {
std::cout << "final catch\n";
return 4;
}
std::cout << "end of program\n";
return 0;
}
Instead, this is what happens when I compile and run:
C:\Users\...\Part 1>g++ cp_bug.cpp -std=c++17
C:\Users\...\Part 1>a.exe
Start of Try-Catch
C:\Users\...\Part 1>

it would be more logical to do something like that:
int main(){
try {
std::cout << "Start of Try-Catch\n";
int a = 13;
int b = 0;
if(b==0)
throw std::string("Passed the div by zero issue\n");
int p = a/b;
std::cout << "printing p: " << p << std::endl;
} catch (std::string e) {
std::cout << e;
return -1;
}
std::cout << "end of program\n";
return 0;
}

Your problem is that division by zero doesn't throw an exception that can be handled. Try the following tutorial instead.
Also this question is duplicated.

Related

Flexible number of fields during Automatic Conversion from JSON boost-1.81.0

Is it possible to convert from a json to a structure with boost-json,
boost-describe if some fields are missing in the json or it has some extra
unneeded fields. In other words to make the json parser a bit more flexible.
The example is taken from https://www.boost.org/doc/libs/1_81_0/libs/describe/doc/html/describe.html#example_from_json with some modification and the templates are removed as I understood they are part of the headers right now.
Here is the code example:
#include <iostream>
#include <boost/describe.hpp>
#include <boost/json/src.hpp>
using namespace std;
struct A {
optional<int> x;
optional<string> y;
};
BOOST_DESCRIBE_STRUCT(A, (), (x, y))
int main()
{
try {
auto json_val = boost::json::parse(R"({"x":5,"y":"Hello world!"})");
auto a = boost::json::value_to<A>(json_val);
cout << "a.x=" << *a.x << ", a1.y=" << *a.y << endl;
}
catch (exception& e) {
cout << e.what() << endl;
}
// error
try {
auto json_val = boost::json::parse(R"({"x":5})");
auto a = boost::json::value_to<A>(json_val); // << exception is here
cout << "a.x=" << *a.x << endl;
}
catch (exception& e) {
cout << e.what() << endl;
}
// error
try {
auto json_val =
boost::json::parse(R"({"x":5,"y":"Hello world!","z":3.1})");
auto a = boost::json::value_to<A>(json_val); // << exception is here
cout << "a.x=" << *a.x << ", a1.y=" << *a.y << endl;
}
catch (exception& e) {
cout << e.what() << endl;
}
}
the output is
[it#test-dev refl1]$ make
g++ -g -O0 -std=c++20 -I/home/it/Snb/boost/1.81.0/include -c -o test1.o test1.cpp
g++ -o test1 test1.o
[it#test-dev refl1]$ ./test1
a.x=5, a1.y=Hello world!
array size does not match target size [boost.json:31 at /home/it/Snb/boost/1.81.0/include/boost/json/detail/value_to.hpp:533:9 in function 'boost::json::result<T> boost::json::detail::value_to_impl(boost::json::try_value_to_tag<T>, const boost::json::value&, boost::json::detail::described_class_conversion_tag)']
array size does not match target size [boost.json:31 at /home/it/Snb/boost/1.81.0/include/boost/json/detail/value_to.hpp:533:9 in function 'boost::json::result<T> boost::json::detail::value_to_impl(boost::json::try_value_to_tag<T>, const boost::json::value&, boost::json::detail::described_class_conversion_tag)']

Throw with no argument inside catch block [duplicate]

This question already has answers here:
Does throw inside a catch ellipsis (...) rethrow the original error in C++?
(1 answer)
C++ re-throw an exception caught by
(2 answers)
In C++, is there a difference between “throw” and “throw ex”?
(8 answers)
Closed 1 year ago.
Our teacher gave us a list of code snippets to prepare for our final exam. For each one, we have to tell either the code compiles, and if so to guess what it outputs. Here is one of them:
#include <iostream>
using namespace std;
float f(int y){
try{
if(y % 2)
throw y / 2;
}
catch(int i){
if (i % 2) throw;
cout << "Number " << i << "is not good! " << "\n";
}
return y / 2;
}
int main(){
int x;
try{
cout << "Give me an integer: ";
cin >> x;
if(x) f(x);
cout << "Number " << x << " not good!\n";
}
catch(int i){
cout << "Number " << i << " is good ! " << "\n";
}
return 0;
}
What does that throw (no argument) really do? Does it just re-throw the current exception, meaing "i"? Is there more I should now or understant from this example ?

c++ No exception thrown while expecting out_of_range

Consider the following source:
void ex8()
{
vector<int> v;
try
{
v.push_back(3);
int i = v[1];
}
catch (exception& e)
{
cout << "pas bon !";
}
}
When executing, no exception is thrown in Release. In Debug, I get a Debug Assertion Failed dialog.
I'am using Visual Studio on Win 10.
Is the vector implementation not supposed to throw an out_of_range exception?
Thank you.
Just an example with [] and at()
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v;
v.push_back(123);
v.resize(0);
try {
std::cout << "at() ";
std::cout << v.at(0) << std::endl;
}
catch (std::exception e) {
std::cout << e.what() << std::endl;
}
std::cout << "[] " << v[0] << std::endl; // all can append
return 0;
}
For me the execution is
at() std::exception
[] 123

Multiply nested try-catch [duplicate]

This question already has answers here:
Pattern to avoid nested try catch blocks?
(16 answers)
Closed 6 years ago.
I have a yaml-cpp which always converts into a std::string, and sometimes also into something else. For example, if the string actually is "3.14", it would also convert into double. I'd first like to try int, then double, then bool, and if that doesn't work, convert to a std::string. Alright, so let's nest those try-catches:
try {
const int a = node.as<int>();
std::cout << "int!" << a << std::endl;
} catch (YAML::BadConversion) {
try {
const double a = node.as<double>();
std::cout << "double!" << a << std::endl;
} catch (YAML::BadConversion) {
try {
const bool a = node.as<bool>();
std::cout << "bool!" << a << std::endl;
} catch (YAML::BadConversion) {
const std::string a = node.as<std::string>();
std::cout << "string!" << a << std::endl;
}
}
}
Hm, the deeper and deeper nesting tells me that this isn't the best way to write that code.
Any suggestions on how to improve the design here? Flat nesting would certainly be advised.
You may put it in a function like:
template<typename N, typename T>
bool tryParseNode(N& node, T& val) {
try {
val = node.as<T>();
return true;
} catch (YAML::BadConversion) {
return false;
}
}
then:
int a;
double d;
bool b;
std::string s;
if (tryParseNode(node, a) {
std::cout << "int!" << a << std::endl;
}
else if (tryParseNode(node, d) {
std::cout << "double!" << d << std::endl;
}
else if (tryParseNode(node, b) {
std::cout << "bool!" << b << std::endl;
}
else if (tryParseNode(node, s) {
std::cout << "string!" << s << std::endl;
}
Try the other way round:
Convert into to a string, then try bool, etc.
Everything within a single try-catch and ignore the exception.
Using exceptions for normal control flow is considered bad practice. In this case, the as method uses the `YAML::convert::decode' method to attempt to convert the node into the requested type returning a false if it fails instead of throwing an exception.
int anInt;
double aDouble;
bool aBool;
if (YAML::convert <int>::decode (node, anInt))
std::cout << "int!" << anInt << std::endl;
else
if (YAML::convert <double>::decode (node, aDouble))
std::cout << "double!" << aDouble << std::endl;
else
if (YAML::convert <bool>::decode (node, aBool))
std::cout << "double!" << aBool << std::endl;
else
std::cout << "string!" << node.as <std::string> () << std::endl;
which could be further simplified to
template <typename value_type>
std::optional <value_type> decode (YAML::Node const & Node)
{
value_type Value;
if (YAML::convert <value_type>::decode (node, Value))
return { Value };
else
return {};
}
if (auto anInt = decode <int> (node))
std::cout << "int!" << *anInt << std::endl;
else
if (auto aDouble = decode <double> (node))
std::cout << "double!" << *aDouble << std::endl;
else
if (auto aBool = decode <bool> (node))
std::cout << "double!" << *aBool << std::endl;
else
std::cout << "string!" << node.as <std::string> () << std::endl;

testing "Try and Catch"

In this program, I am using template class, I have a header file and this is my main file. I am having trouble displaying the (".....") IndexOutOfBounds and displaying it on the screen.
#include "XArray.h"
#include <iomanip>
#include <string>
using namespace std;
template<class T>
void afriend ( XArray<T> );
int main()
{
XArray<double> myAD(18);
myAD.randGen(15, 100);
cout << myAD.getType() << endl;
cout << setprecision(1) << fixed << "\n\n Unsorted: " << myAD;
myAD.sort();
cout << "\n Now Sorted: " << myAD;
cout << "\n\n";
**try
{
cout << "A[-5] = " << setw(6) << myAD[-5] << endl;
}
catch(XArray<double>::IndexOutOfBound e)
{
e.print();
}
try
{
cout << "A[8] = " << setw(6) << myAD[8] << endl;
}
catch(XArray<double>::IndexOutOfBound e)
{
e.print();
}**
cout << "\n\n" << setprecision(2) << fixed;
cout << "Size = " << setw(6) << myAD.getSize() << endl;
cout << "Mean = " << setw(6) << myAD.mean() << endl;
cout << "Median = " << setw(6) << myAD.median() << endl;
cout << "STD = " << setw(6) << myAD.std() << endl;
cout << "Min # = " << setw(6) << myAD.min() << endl;
cout << "Max # = " << setw(6) << myAD.max() << endl;
return 0;
}
There is the Array.h file posted as a dropbox link
Array.h
The code for operator[] in Array.h is:
template <class T>
T XArray<T>::operator[] (int idx)
{
if( (idx = 0) && (idx < size) )
{
return Array[idx];
}
else
{
throw IndexOutOfBound();
return numeric_limits<T>::epsilon();
}
}
Although the question is somewhat obscure, give a try to these suggestions.
Firstly, it can happen that XArray<>::IndexOutOfBounds have no proper copy ctor. You can try catching by const reference to workaround that:
try
{
...
}
catch(const XArray<double>::IndexOutOfBound& e)
{
e.print();
}
Index operator in standard library containers does not check for bounds, there is a special getter that does the check called at(). If the XArray class is designed with standard library in mind, it could behave similarly.
However to get more adequate response you need to be more specific describing the trouble you are having.
I'm still wondering what exact question is.
However, I'm understanding the question is that how I can use 'catch' by using 'IndexOutOfBound'.
#include <exception>
#include <iostream>
using namespace std;
template <typename T>
class Array
{
private:
int m_nLength;
T *m_ptData;
public:
...
...
T& operator[](int nIndex)
{
//assert(nIndex >= 0 && nIndex < m_nLength);
if(nIndex < 0 || nIndex > m_nLength)
{
throw myex;
}
else
{
return m_ptData[nIndex];
}
}
//class definition for 'IndexOutOfBound'
class IndexOutOfBound: public exception
{
public:
virtual const char* print() const throw()
{
return "Exception occured 'Index Out Of Bound'";
}
}myex;
};
int main()
{
Array<double> arr(3);
try
{
arr[0] = 1;
//exception will occur here.
arr[4] = 2;
}
catch(Array<double>::IndexOutOfBound &e)
{
cout << e.print() << '\n';
}
return 0;
}
Here is no 'XArray.h', so I've written a sample array class for example.
The problem is in the operator[] function. The code idx = 0 sets idx to 0. So all of your calls to operator[] will return the first element, and therefore there is no out-of-bounds error unless the array is empty.
You probably meant to write if ( idx >= 0 && idx < size ).
BTW the throw aborts the function, it makes no sense to return after throw.