Use gdb to find where to throw a C++ exception

Here is a simple example about how to find where to throw a C++ exception.

#include <iostream>
#include <stdexcept>

using namespace std;

void computeIntegral() {
  throw std::runtime_error( "Input data is not valid" );  
}

int main(int argc, char** argv) {
  try {
    computeIntegral();
  } catch( std::runtime_error &e ) {
    cout << "Caught an exception: " << e.what() << endl;
  }
  
  return 0;
}

Build and run it.

g++ testException.cpp --std=c++14
./a.out
Caught an exception: Input data is not valid

Now use gdb to debug it.

gdb --args ./a.out
(gdb) catch throw
Catchpoint 1 (throw)
(gdb) r
...
(gdb) bt
#0  __cxxabiv1::__cxa_throw (obj=0x614ca0, 
    tinfo=0x6020c0 <_ZTISt13runtime_error@@GLIBCXX_3.4>, 
    dest=0x400a40 <_ZNSt13runtime_errorD1Ev@plt>)
    at ../../../../gcc-8.3.0/libstdc++-v3/libsupc++/eh_throw.cc:80
#1  0x0000000000400bd5 in computeIntegral() ()
#2  0x0000000000400c00 in main ()

Achieve polymorphism using pointer or reference

It is very common to use pointer to achieve polymorphism. For example,

#include <iostream>
 
using namespace std;

// Base class
class A {
public:
  virtual void output() = 0;
};

// Derived class B
class B : public A {
public:
  void output() override {
    cout << "From derived class B" << endl;
  }
};

// Derived class C
class C : public A {
public:
  void output() override {
    cout << "From derived class C" << endl;
  }
};

// Client code
int main(int argc, char** argv) 
{
  A *b = new B;
  A *c = new C;
  
  int flag = 0;
  cin >> flag;
  
  auto t = flag == 0 ? b : c;
  t->output();
  
  delete b;
  delete c;
  
  return 0;
}

Build the above code, and test it.

g++ -o testrefer main.cpp  --std=c++14

./testrefer
0
From the derived class B

./testrefer
1
From the derived class C

What if there are two objects of derived classes instead of two pointers of them in the client code? The answer is using reference.

// Client code
int main(int argc, char** argv) 
{
  B b;
  C c;
 
  int flag = 0;
  cin >> flag;
  
  auto& t = flag == 0 ? static_cast< A& >( b ) : static_cast< A& >( c );
  
  t.output();
  
  return 0;
}

Build and test it, and get the same output.

g++ -o testrefer main.cpp  --std=c++14

./testrefer
0
From the derived class B

./testrefer
1
From the derived class C

Use xmgrace to plot a curve skipping the first row

Sometimes the file that is read by xmgrace has a header like below:

Ratio
0.67
0.52
...

If use xmgrace directly, we cannot plot the curve as expected.

I haven’t found the way of using xmgrace only. Instead, I only found how to specify columns using xmgrace.

With the help of other tools, here is a way to work around.

tail -n +2 a.txt | xmgrace -pipe

or

sed 1d a.txt | xmgrace -pipe

What if the derived class in CRTP is a template class?

CRTP (Curiously Recurring Template Pattern) is a very useful skill to achieve static polymorphism.

How to achieve CRTP if the derived class is a template class? Here is an example.

#include <iostream>
#include <string>

using namespace std;

// Base class A
template< typename Type, template< typename > class Derived >
class A {
  public:
    A() = default;
    virtual ~A() = default;
    
    void output( Type num ) {
      cout << "From base A, ";
      static_cast< Derived< Type > * > (this)->speak( num );
    }
    
  protected:
    virtual void speak( Type num ) = 0;
};

// Derived class B, override the protected method speak()
template< typename Type >
class B : public A< Type, B > {
  friend class A< Type, B >;
  public:
    using A< Type, B >::A;
    
  protected:
    void speak( Type num ) override {
      cout << "I am B, and I got " << std::to_string( num ) << endl;
    }      
};

// Derived class C, override the protected method speak()
template< typename Type >
class C : public A< Type, C > {
  friend class A< Type, C >;
  public:
    using A< Type, C >::A;
    
  protected:
    void speak( Type num ) override {
      cout << "I am C, and I got " << std::to_string( num ) << endl;
    }   
};

// Client code
int main(int argc, char** argv) {
  B< float > b;
  b.output( 5 );
  
  C< float > c;
  c.output( 8 );

  return 0;
}

Use g++ to compile the above code, and get the outputs.

g++ -o crtptest main.cpp --std=c++14
./crtptest
From base A, I am B, and I got 5.000000
From base A, I am C, and I got 8.000000