Archive for the ‘C++’ category

set up CppUnit Eclipse plugin (ECUT) for C++ on Ubuntu

September 24th, 2010

Here I will show how to use CppUnit to do Unit Testing for C++ within Eclipse with the plugin ECUT.

NB: the OS here is Ubuntu 10.4. As for other OS, you have to figure out how to install CppUnit by yourself, and change the build path accordingly in configuration.

* First, install CppUnit. On Ubuntu, we can install from the repository:

sudo apt-get install libcppunit-1.12-1 libcppunit-dev

* Get the ECUT plugin from http://sourceforge.net/projects/ecut/ and install it in Eclipse with the software installer in the Help menu.

* Configur the connector in Eclipse in Window -> Preferences -> C/C++ -> ECUT -> Configure (Add “Library location: /usr/lib/libcppunit.a” and “Include location: /usr/include/cppunit”).

Now the configuration is done. Now let’s see a sample project. I’ll use the official ECUT Demo: http://sourceforge.net/projects/ecut/files/ECUT%20Documentation/R1.0-M3/EcutDemo_M3.zip/download.

* Create a empty C++ project in Eclipse called: EcutTest.

* Create 2 source folders within the project: src & test. src will be place for application application source files, while test is for test cases.

* Copy the 3 source files from EcutDemo_M3/src into the project src folder.

* Build a Debug version, and run it. This is just to test whether the project works. You will find the output: “result: 13″ if it build the project right.

Now it’s the time to connect CppTest with the project.

* Right click on the project name “EcutTest”, and choose ECUT -> Apply Connector. Select the one and only Connect “CppUnit Connector”, and “Create build configurations” as well.
– Note: ignore the warning in the image below, because I have applied the connect before.
– If you need a configuration: Library location is: “/usr/lib/libcppunit.a” and Include location is: “/usr/include/cppunit”.

* Create a Test case. Right click on module1.c -> New -> ECUT Test Case. Note: ignore the error message in the image below, because I have already created the Test Case.

* edit the automatically created source file test/module1Test.cpp a little bit to correct the Include Path.

change the source:

#include “module1.c”

into

#include “../src/module1.c”

* Create a run configuration to run the Test Case: Run -> Run Configurations -> Right click on ECUT -> New:

ECUT Test Case Run Configuration

* Run the test by clicking on Run as shown in the above image. Both of the 2 test cases should fail, because in the test method body, they return false directly.

* OK, now everything is done. It’s the time to do some real work. Change the function module1Test::testadd as bleow:

void module1Test::testadd() {
CPPUNIT_ASSERT(24 == add(12, 12));
}

And run the Test again, you will find 1 case is passed, and 1 case fails.

Details of assertions can be found here: http://cppunit.sourceforge.net/doc/1.11.6/group___assertions.html.

C++ constructor

May 30th, 2010

C++ derived classed will call parent’s default constructor by default at the beginning of construction. Note, only at the beginning. It’s not like Java, you can call super() at the any time you want.

And if you want to call a parent constructor with parameters (of course, also at the beginning of the construction), you can do it like this:

Derived(int ap, int bp) : Base(ap, bp) {/* do something you want in the derived class constructor */}

The destructor will also call the parent destructor.

Here is a example:

#include <iostream>

using namespace std;

class Base {
public:
int a;
int b;

Base() {
cout << “base constructor” << endl;
}

Base(int ap, int bp): a(ap) {
b = bp;
cout << “base constructor with param” << endl;
}

~Base() {
cout << “base destrctor. a: ” << a << “, b: ” << b << endl;
}
};

class Derived : public Base {
public:
Derived() {
cout << “derived constructor” << endl;
}

Derived(int ap, int bp) : Base(ap, bp) {
cout << “Derived constructor with param” << endl;
}

~Derived() {
cout << “derived destrctor. a: ” << a << “, b: ” << b << endl;
}
};

int main() {
/*
Base b(3, 4);
*/
Derived d(3, 4);
}

c++ vector memory taken

March 2nd, 2010

Here is a experiment about how much memory will a vector array take with different size on a 64bit machine with a 64bit OS (Ubuntu).

Vector Arr Size   Memory
10K * 1             208K
10K * 10           688K
10K * 100         5.4M
10K * 1000       52.8M
12K * 100         12.3M
100K * 10         10M
300K * 10         30M
300K * 100        158M

Note: 10K * 1 means an array of 10K vectors with each vector having 1 int element.

array initialization in C++

March 1st, 2010

An important point about array initializaiton in C++ is that a static array won’t assign default values to it’s elements, but a dynamic one will. At least it’s like this with g++.

Here is an example:

int main(int argc, char* argv[]) {
  size_t n(100000);

  // This works
  unsigned short *ords;
  ords = new unsigned short[n];
  // or
  //ords = new unsigned short[n]();

  // This doesn't work
  //unsigned short ords[n];

  bool noProblem = true;
  for(size_t i = 0; i != n; ++i) {
    if(ords[i] != 0) {
      noProblem = false;
      break;
    }
  }
  if(noProblem)
    cout << "No problem" << endl;
  else
    cout << "It doesn't work" << endl;

}

How to define template functions/classes in different files

January 27th, 2010

Here is a long discussion: http://bytes.com/topic/c/answers/648102-header-file-template-functions-classes.

In a word, the simplest way in practice is to put the definition (which at the same time is delearation) of the template functions/classes only in the .h header file, but not to separate the definition into a .cpp file.

Also see: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12.

How many elements should be set in vector when using set_intersection?

January 27th, 2010

I tried this example on this page: http://www.cplusplus.com/reference/algorithm/set_intersection/ which is listed below:

// set_intersection example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  vector<int> v(10);                           // 0  0  0  0  0  0  0  0  0  0
  vector<int>::iterator it;

  sort (first,first+5);     //  5 10 15 20 25
  sort (second,second+5);   // 10 20 30 40 50

  it=set_intersection (first, first+5, second, second+5, v.begin());
                                               // 10 20 0  0  0  0  0  0  0  0

  cout << "intersection has " << int(it - v.begin()) << " elements.n";

  return 0;
}

I also tried to change the vector’s initial length to 1, 2, 20. All to them worked fine. However, when I tried this (with vector’s initial length set to 10) on two sets which have 49 common objects. The memory leaked. So in practice, how large do we need to set the vector?

using self-defined comparator with binary search in C++

January 22nd, 2010

For example, you want std::pairs, which normally compare with their first values (the keys),  to compare with their second values. You could write a comparator yourself and use it to compare the pairs.

bool PairCompF (const std::pair<node_t, result_t> &lhs, const std::pair<node_t, result_t> &rhs) {
return lhs.second < rhs.second;
}

int main(int argc, char* argv[]) {

pair<int, int> a(12, 44);
pair<int, int> b(23, 30);
pair<int, int> c(30, 23);
pair<int, int> d(40, 23);
pair<int, int> e(50, 10);
vector< pair<int, int> > v;
v.push_back(e);
v.push_back(d);
v.push_back(c);
v.push_back(b);
v.push_back(a);

cout << “lower bound of 23 is ” << (lower_bound(v.begin(), v.end(), c, PairCompF) – v.begin()) << endl;
cout << “upper bound of 23 is ” << (upper_bound(v.begin(), v.end(), c, PairCompF) – v.begin()) << endl;

return 0;

}

MTL 4 Installation

January 6th, 2010

The installation of MTL 4 is extremely easy. Actually, we only need to download 2 packages (boost and mtl4) and extract them locally if we don’t want to run the tests and example programs. The complete installation guide please you could always refer to the official site: http://www.osl.iu.edu/research/mtl/mtl4/doc/install.php3.

  • The first step is to download and extract boost which is used by MTL 4. Go to boost’s homepage http://www.boost.org/, and download the newest version of boost. Suppose you save it on your local path as /home/me/programs/. Extract it as boost_x_xx_xx, such as boost_1_41_0. So your boost folder is /home/me/programs/boost_x_xx_xx, now.
  • The second and the final step is to download and extract mtl4. Go to http://www.osl.iu.edu/research/mtl/mtl4/download.php3, choose the latest version and download it to, for example, /home/me/programs. Extract it. Now your mtl folder would be /home/me/programs/mtl4.

Now it’s time to use the mtl library. You can include whatever you want like this:

#include <boost/numeric/mtl/mtl.hpp>

And compile your program like this (suppose you are using the GNU C++ compiler):

g++ -I/home/me/programs/mtl4 -I/home/me/programs/boost_x_xx_xx -O2 vector1.cpp -o vector1

Please refer to http://www.osl.iu.edu/research/mtl/mtl4/doc/vector_def.html to see a detail Hello World program.

If you don’t like to include the boost path every time you compile your program, then you can install it as a binary library on your machine. You can always check the offical Boost Get Started. And here is a instruction about installing boost on Gentoo and Debian/Ubuntu: Installing C++ Boost on Gentoo and Debian/Ubuntu.

ATLAS installation memo

January 5th, 2010

Tried to install ATLAS 3.9.20 according to the instruction: doc/atlas_install.pdf.

As said, the simplest way is:

bunzip2 -c atlas3.9.x.tar.bz2 | tar xfm -    # create SRCdir
mv ATLAS ATLAS3.9.x                            # get unique dir name
cd ATLAS3.9.x                                       # enter SRCdir
mkdir Linux_C2D64SSE3                         # create BLDdir
cd Linux_C2D64SSE3                              # enter BLDdir
../configure -b 64 -D c -DPentiumCPS=2400 # configure command
–prefix=/home/whaley/lib/atlas          # install dir
–with-netlib-lapack-tarfile=/home/whaley/dload/lapack.tgz
make build                                     # tune & build lib
make check                                    # sanity check correct answer
make time                                      # check if lib is fast
make install                                   # copy libs to install dir

There are some things to be noticed:

  • remember to change the options for configure. For example, your CPU info can be found out by $cat /proc/cpuinfo;
  • make sure fort77 is installed;
  • make sure gfortran is installed otherwise an error “gcc: error trying to exec ‘f951′: execvp: No such file or directorygcc” would be reported.