Sunday, July 10, 2005

Conventionally, std::cin, std::cout are buffererd and std::cerr is not buffered. Unbuffered streams are written to device immediately. In general, ofstreams are buffered. You can make a stream unbuffered by invoking setbuf(0,0).

For example,

ofstream of;of.setbuf(0,0); // makes it unbuffered.

You can force a buffered stream to flush the contents using std::endl. Other interesting thing is to tie an buffered output stream with a buffered input stream. What this means is, whenever you want to accept an input from the input stream, the output stream 'tied' to it is flushed automatically.

For example,ifstream in; // a buffered input stream.ofstream out; // a buffered output stream.and in and out are tied together.

then,out << "data 1" << "data 2" << ..... << "data N"; // may or may not occur on screen or file....in >> somevar; // out will be flushed before somevar is input.

You do this by invoking:

in.tie(&out);

tie causes two streams to be synchronized, such that, operations on one stream occur after operations on the other stream are complete. As a last note, by default, the standard objects cin, cerr and clog are tied to cout.

Thursday, July 07, 2005

You can define an union having constructors but a member of class type having constructor is not allowed in union. The reason is obvious: how would the compiler know which destructor to invoke when an object of the union goes out of scope? (for that matter, compiler does not even know which constructor to invoke at the time of creation of an object of such union)

Tuesday, July 05, 2005

In C++, default arguments of global scope functions can be changed easily.

Typically we use a constant expression as a default argument. C++ supports static variables as well as a constant expression for a default argument. We can also redeclare a function signature in a new scope with a different default value.

Default arguments are implemented as global static variables. Therefore, same effect can be achieved if we assign a differnt value to the static varibale. Following code shows this interesting feature.

As a programming guideline, if you need to change the value of default argument, either by redelcaring the function signature or reassignment of static variable, you better not make it a default argument and keep it a simple argument.

Saturday, July 02, 2005

My recent experience of programming in C tell me following things:

1. ALWAYS! ALWAYS!! ALWAYS!!! initialize local variables in C. pointer, integers, chars, user defined structures whatever it is. Initialize. Uninitialized variables are especially dangerous in highly recursive programs because somewhere, at some invocation the variable assumes the 'bad' value and catastrophic results happen somewhere down in the call stack. You can initialize local structured data-types such as array and structures using following syntax.

Message m = { 0 } ; This makes all the elements of the structure equal to zero. (Message is a type definition for a struct Message_tag)

int i[5] = { 10 } ; This will make only first element of array i equal to 10, all other will be zero. Also note that, globals, statics are always by default initialized to zero. This is not the case with locals. But little more typing can save you lot of trouble.

2. Containers should hold your data, followed by local variables and lastly local pointers. I prefer to allocated as much data on stack as possible. The language takes care of deallocating memory for you. For example, I have a list of messages in C. This is not a std::list<> in C++. Following way avoids many pitfalls.

1. Declare a local variable: "Message m;" 2. Ask the list to make a copy of message to be added and store the copy in the list. List takes care of creating a copy, copying data. You have to implement list in that way. 3. When extracting out from the list, extract message in a local variable again. (Use pass by reference technique) List copies the data for you in the (reference passed) local variable. List also takes care of deallocating the copy of message it has.

This means you are not holding your data except one local variable at a time. This will save you especially when a recursive function is manipulating lists.