Skip to main content

Posts

buffered/unbuffered C++ streams

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)...

Unions and Constructors

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)

Changing C++ function default arguments

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. ****************************************************************************** #include #include #include static int para=200; void g(int x=para); // default argument is a static variable. void f(int x=7); // default argument implemented in terms of some static varible. int main(void) { void f(int x=70); // redeclaring function ::f f(); // prints f70 g(); // prints g200 para=500; g(); // prints g500 { void f(int x=700); // redeclaring function f...
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 ...
What is wrong if I declare main something like this? const int MYMAX_PARA=10; int main(int argc, char *(*argv)[MYMAX_PARA], char *env[]) printf("%s %s",(*argv)[1],env[2]); When I want to pass a double by reference I use 'pointer to double'. When I want to pass a structure by reference I use 'pointer to structure'. Then why not 'pointer to array' when passing array by reference? Why is there and exception in case of arrays? I try to think why array-to-pointer 'decay' occurs in C/C++, I think of above example. To me, the answer is about simplicity of coding. In above example, argv++ won't give you next argument but rather next array of arguments. To get next argument you need to do (*argv)[2] (*argv)[3] and so on. So decay simplifies your coding and avoids pointer to array syntax. This rules out char *(*argv)[]. And BTW, third parameter in main is 'recommended' by standard. Standard demands: int main() { /* ... */ } AND int main(int a...
Some syntax clarification: This is a short syntax tutorial for upcoming posts. int *p; // a pointer to an integer int &p; // a reference to an integer const int *p; // pointer to a constant integer int const *p; // same as above int * const p; // constant pointer to an integer const int * const p; // constant pointer to a constant integer const int * const *p; // a pointer to a constant pointer to a constant integer But references are implicitly constant, therefore, int & const p; // is not allowed const int & const p; // is not allowed int (*q)[10] // a pointer to an array of 10 integers int (&q)[10] // a reference to an array of 10 integers. Yes, they are supported. int (*q)(char) // a pointer to a function int (&q)(char) // a reference to a function int *&q // A reference to a pointer to an integer. And this too is supported. int (*&q)[10] // a reference to a pointer to an array of 10 integers. Similar to passing integer by reference to change it inside a...
Reading entire file in one go. Solution 1: std::ifstream in("circle.cc"); std::istreambuf_iterator < char > begin(in), end; std::string str(begin, end); Solution 2: std::ifstream input("circle.cc"); std::ostringstream temp; temp std::string str = temp.str(); In both the cases, std::cout will print out entire file. Perl solution: open CIRCLE, "circle.cc"; @mylist = <CIRCLE> ; close CIRCLE; C++ and Perl both take 3 lines of code. Not bad for a system programming language!!
An interesting consequence of decay related rules of pointers and references is that seemingly correct C++ code fails to compile. We have a max() template with pretty obvious implementation for basic types. template < typename T > T & max (T &a,T &b); but, max("APPLE","PEAR"); Gives an error, because type of "APPLE" is const char [6] type of "PEAR" is const char [5] T can't be "const char [6]" AND "const char [5]" at the same time!! No array-to-pointer decay occurs here. Above thing will work for following declaration of max template < typename T > T max (T a, T b); Here T is char *!!
pointer cause decay, references do not. Decay means loss of type information. In C and C++, an array name 'decays' to pointer to the first element. The information lost is basically the number of elements in the array. This difference should be manifested by sizeof() operator in function f() and g(). References keep that information with them. such as 'constness' of int. Function names are also said to 'decay' into pointer to the function if only function name is used. But such a function pointer retains, I think, everything about the function signature: parameter types and function return type; even in C. With following declarations, template < typename T > void f (T); template < typename T > void g (T &); and with these declarations, double x[20]; int const seven = 7; f(x); T is double * g(x); T is double [20] f(seven); T is int g(seven); T is int const f(7); T is int g(7); T is int, ERROR can't pass 7 to int& Therefore, pointer cause d...
I love C++ programming language for its power and complexity!! To me, its enormity and complexity has been an incessant source of different features to understand. C++ is still evolving, therefore, I'll have new stuff to learn for quite a while. Many of the C++ features are quite exotic and thats why I am interested in them. On this blog you will find exotic C++ stuff such as core language features, idioms, patterns, C++ emerging standards etc. This is not a beginners blog. You will find here intermediate to advanced level material on C++. I also plan to put new C++ material as I learn it. You might find thoughts presented here already presented somewhere else like popular C++ books, magazines, e-zines, websites, blogs etc. This is becasue I learn from these popular sources. Site Feed URL: http://cpptruths.blogspot.com/atom.xml WhoamI? I am not a guru in C++. But I put serious efforts into learning anything remotely related to C++. More about me: http://www.cs.nmsu.edu/~stambe