Thursday, November 22, 2007

latex note: minipage with borders

One way to add borders to a minipage is embedding it into an fbox. For example:

\fbox{
\begin{minipage}[t]{0.5\textwidth}
...
\end{minipage}
}

Friday, November 09, 2007

C++ note: initializers in multiple inheritance

Here is a tutorial on C++ multiple inheritance.

A C++ class can inherit multiple base classes. If these base class still have base classes, they will be initialized separately by default. (For each parent class, the subclass will contain the inherited structures) For example, suppose B and C derive from A, and D derive from B and C, D will have two copies of A. One inherited from B, and the other from C.

In some occasions only one copy of A is needed in D. This type of inheritance is enabled by letting B and C virtually derive from A. By virtual inheritance, B and C no longer encompass the structure of A into their structure, but include a pointer to the A structure in their vtables. When D derive from B and C, the compiler generates only one A structure that is shared by B and C.

Here comes a question: in the constructor of D, what structures do we need to initialize?

class A {
public:
   int a;
  A ( int i ) : a (i) {}
}

class B : virtual public A {
public:
   B ( int i ) : A(i) {}
}

class C : virtual public A {
public:
   C ( int i ) : A(i) {}
}

class D : public B, public C {
   D ( int i ) : A(i), B(i), C(i) {} // <-------------
}

In the above example, D has to initilize A, B and C in its constructor. The initialization of A is mandatory even though both B and C do have the initializers in their constructor. When D is constructed, the initializers of B and C will not assign any value to A by default. This fact can be observed by removing the initialization of A in D, and printing the a field from D-object.

Thursday, November 08, 2007

C++ note: avoid allocating large structures in the stack

Unexpected segmentation fault when calling a function can be caused by big memory allocation in the stack. The following piece of code will fail.

class Big {
   int data[10000000000];
};

void test() {
   cout << "entering test";
   Big big;
}

void main(int argc, char** argv) {
   test();
}

The reason is this: when test() is called, the variables declared in this function are put to the stack ( which is a special area of memory for function calls, commonly supported by a stack pointer in the CPU architecture ). The size of the stack is limited, and putting too much data in it can cause unexpected errors without warning. ( Note that compilers may choose to push stack before any executions, and therefore the "entering test" hint might not be printed. ) This kind of error is hard to trace during debugging. With new CPU architectures, the stack size may be improved, but this trap is still commonly seen nowadays.

To void such segmentation faults, we need to put the big structures into the heap. Two methods can be used. One is allocating memory inside the class:

class Big {
   int *data;
   Big() { data = new int[10000000000]; }
   virtual ~Big() { delete data; }
};

The other is allocating memory inside the function instead:

void test() {
   cout << "entering test";
   Big *big = new Big;
   delete big;
}

Wednesday, November 07, 2007

C++ note: pointer and reference

The semantics of the * operator is to get the value from a pointer. When it is used as a reference, *p converts the pointer to the reference of the object it points to. This is illustrated with the following example.

void reference( int &i ) { i = 4; }

void testReference() {
   int i=5;
   int *p = &i;
   reference( *p );
   cout < < i << endl;
}

As can be seen from the output (4), the i in the testReference method is actually modified. This shows the semantics of the * operator, when used as a reference.

Friday, November 02, 2007

C++ note: predefined macros

The standard C++ compilers all support the following macros:

__DATE__ - a string literal containing the date when the source file was compiled, in the form of "Mmm dd yyyy".

__FILE__ - a string literal containing the name of the source file.

__LINE__ - an integer representing the current source line number.

__STDC__ - defined if the C compiler conforms to the ANSI standard. This macro is undefined if the language level is set to anything other than ANSI.

__TIME__ - a string literal containing the time when the source file was compiled, in the form of "hh:mm:ss".

__cplusplus - defined when the compiler supports c plus plus.

These macros can be used anywhere in the source code, just as if they were defined by the #define directive. Their value changes according the the specific file and line in the source code. Therefore, we can use them to implement error reporting that includes file and line numbers in C++ source code.

#define REPORT(x) cerr << endl << "In " << __FILE__ << ", line " << __LINE__ << ": " << endl << x << endl; cerr.flush();