C++

Of Boost and Men

Boost is a great collection of libraries. The functionality is so diverse and the quality is so high and the design is so careful that it’s almost part of the standard C++ library (of course, many of Boost’s sub-libraries has already been accepted for inclusion into the next version of C++ standard library with little or no modification, and more are scheduled for discussion.)
People who develop Boost are fantastic software designers and all C++ gurus. I consider myself a seasoned C++ programmer and I can’t honestly say that I can follow their discussions without extensive reference look up and pondering (the times that I know what they are talking about, that is!) This has led to both Boost’s greatest strengths and weaknesses.
Obviously, when you have many great developers and well-defined, open and democratic processes, you’re gonna get good FOSS. It also leads to a perceived elitism and high entry barrier. From the “outside”, it looks like Boosters all want to keep the glory to themselves, and that they would shoot down any library submitted for inclusion by an “outsider.” I’ve not been around the Boost discussion lists long enough and I haven’t been paying a close enough attention to know this for sure, but it seems to me like most people there are volunteers, more interested in quality and advancement for their (and my) beloved language, rather than glory-seeking adventurers after fame and fortune.
Also at first glance, Boost might seem like a bag of cryptic and hard-to-learn libraries, shrouded in mystery and magic. It is not quite like that, but given the fact that C++ is a difficult language (yeah, your hunches in your freshman year were right, if not the reasons behind them) you should expect some complexity is some of its (arguably) most advanced libraries.

If nothing else, use Boost’s thread, filesystem, serialization and async I/O libraries. The thread library is pretty much already a part of standard C++ anyway, so you might as well learn to use it (not that it is hard to use.) Lack of portable file system access has always been a weakness on C and C++. The serialization library is so unintrusive and fantastic, that it will find its way and place in any non-trivial program that we’ll ever write. And asio has so much needed functionality, that I’m just itching to try it out.
And when you are already using one part of Boost, why stop there? Use anything and everything you can. Not blindly, of course, but prefer well-designed, well-developed and well-tested libraries to some small code snippet you find off the web. And when using Boost, delve into it and see how it is implemented. It’s educational and more often that not even enlightening for the likes of me.

VN:F [1.0.8_357]
Rating: 5.5/10 (2 votes cast)

C++

Comments (4)

Permalink

Boost 1.36.0 is Out

Shame on me! Boost 1.36.0 got released and I didn’t even know it was coming this soon. It’s been several weeks that I haven’t read the mailing list. Think of all the C++ goodness I’ve lost!
I’ll get it off the SVN (if my ISP let’s me; damned idiots) and build it in a few hours, and I’ll try to upload it.

VN:F [1.0.8_357]
Rating: 1.0/10 (1 vote cast)

C++
noteworthy

Comments (0)

Permalink

Fun with C++: Useless Consts?

Many C++ programmers see the keyword “const” as something redundant that only gets in the way. They curse Stroustrup and his ancestors each time they encounter a const-related compile error because of that view and fail to use it correctly quite often (note that I’m not saying that I’m not one of these people, but I curse neither Stroustrup nor anyone else.)

If you ask them about the purpose of the const keyword, they would give you the classic answer that any C++ textbook gives: variables declared as consts cannot be changed by the programmer, and const class methods cannot modify their instance data (and can be called on const class instances), etc.

The programmer may give you the textbook answer (or some mutilated version of it, depending on which textbook she read and how much of it she actually remembers,) but she is wondering with herself who will stop the other programmer to change the header file and remove the const from the declaration? Who is there to prevent her from doing so?!

She may even make a conjecture that if she removes all the consts from all her source files and headers (including standard and 3rd party headers she uses,) then her programs will continue to compile and work just fine (after all, the const keyword has no runtime effect. It’s an exclusively compile-time construct, is it not? So if her programs used to work, and they compile after removing all consts, they should continue to run without problem.)

If she is a little bit more sophisticated and skilled in C++, she knows that the C++ compilers differentiates between functions that take const arguments and those that take exactly the same arguments, but not const. This fact lets you have function overloads that only differ in constness of their arguments. The same is also true for template specializations (which is a form of overload anyway.)

So this more sophisticated C++ programmer will conjecture that if she removes all the consts and eliminates the redundant overloads (which were nothing but nuisances to begin with) then her programs will compile.

Now, is she right? Is this the case with const?
(I should say that I know of one case that is not so (the program will not compile without the the const) but it’s not a common case. I’ll write about that in a later post (if no one guesses it first.) I’m genuinely interested in other such cases.)
(Another note. The use of const frees the compiler to do some optimizations that may not be safe with a non-const object. My question is about correctness and not about performance.)

VN:F [1.0.8_357]
Rating: 5.5/10 (2 votes cast)

C++
code
programming

Comments (2)

Permalink

Fun with C++: When Parentheses Don’t Call!

Just a quick one. Most of us have come to think of parentheses as sometimes necessary but always harmless little creatures. Our view is that unless parentheses change the order of evaluation (and therefore the meaning) of an expression, they are completely harmless.
Well, while that is true almost by definition, there are cases that we might not realize the meaning of an expression is being changed. One such case is in the presence of the versatile and extremely useful (and possibly massively pain inducing) comma operator (’,‘.)
You see, the comma has two uses in C++ language: as an operator and as a separator for many different lists of things in the language grammar (function arguments, object declaration, etc.) In the first context, a pair of parentheses work exactly as anyone would expect; in the second, probably not. The problem is that the use of commas in the first context is not common at all, while the commas of second kind riddle any and every C++ source file. It’s mixing the meaning of the uses that’ll lead to potentially cryptic compile errors (what a shocker! Cryptic compile error messages in C++?!), or worse, logical bugs that will make you wish you were coding in machine language.

Just for the sake of comprehensiveness, while I know that you all know how the comma operator operates, I’m gonna describe its workings anyway. The comma operator has the lowest precedence among all the operators in C++ and it is a left-associative operator (meaning “a, b, c” will be evaluated as “(a, b), c“.)
An expression of the form “a, b” (where a and b are expressions themselves (and not statements)) will always evaluate a first, and then b and will return the evaluated value of b.
Please believe me when I say that overloading this operator can achieve magic and convenience one can only dream of in C++! Just see the Boost.Assignment library for a sample.

One place that the implicit mixing up of the meaning of comma could cause trouble is in function calls. Suppose that a function X accepts two arguments. Now, if instead of X (a, b) someone writes X ((a, b)) then they will be given a compile error saying that function X does not take one argument(s);-) . This is because the extra pair of parens have changed the meaning of the comma from a simple argument list separator to a C++ operator.
This will not confuse any C++ programmer out of her first few months with the language, and will be obvious and easy to find and fix. But what if the extra pair of parentheses is the result of a macro expansion? Then you’ll have to chase down the macro definition. Still not very hard, because the compiler will catch you. But what happens if the X function has an overload with a single argument, incidentally with a type compatible with b? What happens if the function takes more than two arguments and has many overloads and it’s called like this: X (a, (b, c), d, (e, f, g))?
I should probably list this as another macro pitfall. Take care where you put parentheses! Don’t just slap them whenever you’re in doubt!

VN:F [1.0.8_357]
Rating: 5.5/10 (2 votes cast)

C++
code

Comments (0)

Permalink

C++ “Glasses”!

The Slashdotters put together a list of questions for Bjarne Sroustrup to answer a while back. The Q&A is interesting on its own, but this comment by an anonymous coward (as they are called on /.) is the funniest piece of writing I’ve read in a long time!
Read the Q&A and the rest of the comments too, if you have time.

VN:F [1.0.8_357]
Rating: 5.5/10 (2 votes cast)

C++
hilarious
noteworthy
programming

Comments (3)

Permalink

Fun with C++: Metaprogramming, Part 1

Metaprogramming can mean many things, but all of them can be made to (loosely) fit under the description of “writing programs that write or rather describe (a class of) other programs.” A classic and somewhat useless sample of this is writing a program that prints it’s own source code. My first real contact with this field came from working with YACC. The rule file one writes to be fed to YACC, is kind of a metaprogram.
As a better example, if you could write a program that would accept a set of strings and generate a C++ program that would implement a “perfect hash function” that would hash those N input strings onto N collision-less values, then you’d have written a metaprogram. (Note that you are not implementing a hash function; you are writing a program that implements many hash functions based on the input.)

Now, these metaprograms can be in any language and output any language. If you write one in C++ that produces C++, then you have to run your compiler twice to get to the final usable program. Not really convenient, but it is used in the real world. For example, that perfect hash function generator example is exactly how gperf works.
On a cooler side, there’s already a couple of other mini-languages that any C++ compiler package can understand, e.g. the preprocessor language. I’m the first one to admit that writing a program only in preprocessor is like having trying to open a locked door with your head, but it’s not entirely without merits and fantastic experiences.

OK, so let’s get down to it. Before we can program in any language, we should know how some basic ideas like logic, conditions, repetition, etc. are expressed in that language. First off, doing loops a la “for” and gang is really really hard to do in preprocessor (I’d say impossible, but I’ve seen Boost.Preprocessor!) Fortunately, C++ preprocessor language does support a form of recursion (guess how?) and we can use that facility both as loops and as subroutines.
If you think about it, you’ll find out that the preprocessor’s programming model is not unlike digital logic circuits, with all the variables, inputs and outputs being single bits (whether a specific macro has been #defined or not) and the only operations being ANDs, ORs and NOTs. Although the preprocessor can assign arbitrary integers to macros and can compare them, but cannot do arithmetic on them.
As a first example, let’s see how an XOR logical function with two one-bit inputs can be implemented.

1
2
3
4
5
#if (defined(IN_a) && !defined(IN_b)) || (!defined(IN_a) && defined(IN_b))
    #define OUT_a
#else
    #undef OUT_a
#endif

That’s it. Not very complex or revolutionary, but this idea can be taken far. What if we put the above code in a header file, and #include that header whenever and wherever we need a 1-bit XOR? Of course, the parameters to that XOR are always the same (think of them as global variables) but this concept can be use to implement functions and therefore recursion. I’m not going to go into more elaborate examples of recursion. Just let me demonstrate a little more of the preprocessor with another example that actually does something and generates output. I’ve implemented a 1-but full-adder (three inputs: A, B and Carry, and two outputs: A and Carry. The input carry is for reusability.) This example consists of two files; a “OneBitAdder.h” like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
	OneBitAdder.h
 
	Inputs: "IN_X" and "IN_Y" and "IN_C"
	Outputs: "OUT_X" and "OUT_C"
 
	Returns the sum of the inputs. Note that each input and
	output here is one bit: either a macro is defined (it's 1)
	or not (it's 0.)
*/
 
  #if !defined(IN_X) && !defined(IN_Y) && !defined(IN_C)	// 0
	#undef OUT_X
	#undef OUT_C
#elif  defined(IN_X) &&  defined(IN_Y) &&  defined(IN_C)	// 3
	#define OUT_X
	#define OUT_C
#elif  defined(IN_X) && !defined(IN_Y) && !defined(IN_C)	// 1
	#define OUT_X
	#undef OUT_C
#elif !defined(IN_X) &&  defined(IN_Y) && !defined(IN_C)	// 1
	#define OUT_X
	#undef OUT_C
#elif !defined(IN_X) && !defined(IN_Y) &&  defined(IN_C)	// 1
	#define OUT_X
	#undef OUT_C
#else						// 2
	#undef OUT_X
	#define OUT_C
#endif

and the “PreprocessorAdderTest.cpp“:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Set input
#define IN_X
#undef IN_Y
#define IN_C
 
// Compute
#include "OneBitAdder.h"
 
// Display(!) output
#  if !defined(OUT_X) && !defined(OUT_C)
	#pragma message ("--- The answer is 0")
#elif  defined(OUT_X) && !defined(OUT_C)
	#pragma message ("--- The answer is 1")
#elif !defined(OUT_X) &&  defined(OUT_C)
	#pragma message ("--- The answer is 2")
#elif  defined(OUT_X) &&  defined(OUT_C)
	#pragma message ("--- The answer is 3")
#endif	
 
// main is mainly cosmetic.
int main () {return 0;}

I’ve used #pragma message for output here. I’m not sure which compilers support it (I suspect all that matter) but if you want you can use other methods, like using #error.
Create these two files and compile the “.cpp” file (note: just compile it.) There should be a string “— The answer is 2” in your compiler output! See what we did? We just run a program by compiling a C++ source file! Cool, eh?

Of course, getting any real use out of the preprocessor (beside the obvious) is really is not worth the effort, but if you want to see whether you have the hang of it, try writing a 2-bit adder using the above 1-bit adder. It’s not as easy (nor as hard) as it may sound. The samples here were not really good examples for metaprogramming, but I think you can extrapolate from here on if you want to.

I originally (i.e when I started writing this post!) wanted to write about template metaprogramming, but I went in a completely different direction. Maybe next time then.

VN:F [1.0.8_357]
Rating: 5.5/10 (2 votes cast)

C++
code

Comments (4)

Permalink

Fun with C++: Macro Pitfalls, Batch 1!

(UPDATE: Added the 6th item.)

I’m a fan of C/C++ preprocessor macros. I would be very happy if C++ received macros on par in power with those of Common Lisp macros, but that’s only a dream! We have to work with what we have.
Anyways, with use of macros come a lot of potential pitfalls. I’m going to go over a couple of them. I’m sure any C++ programmer is aware of these, but the reiteration would hurt now, would it? I’m also hoping that with your feedback, we can complete these into something referable and usable.

  1. Operator Mishaps From Hell!
    This is a classic example.

    #define SQR(x)    x * x

    Imagine what happens when you use something like SQR(a + b). But as I said, this is a classic example, and any C programmer with half a brain should know enough to avoid this (doesn’t mean it always happens though. We all have our shameful secrets!)
    The moral is: always enclose every usage of macro parameters in parentheses as well as the whole thing. (#define SQR(x) ((x) * (x)))

  2. The Space From Hell!
    #define SQR (x)   ((x) * (x))

    Notice the space between SQR and the (x)? The programmer didn’t! It usually results in a cryptic compile error about something not being a function or about incorrect number of arguments. Easy for more experienced programmers to understand and rectify (usually with a bang to their heads.)
    Also, it’s not hard to imagine cases without any compile errors and severe oddities in runtime behavior. Remember: Compile-time errors and warnings are your friends as long as you pay attention to them! They might be a little hard to understand, but a project with 100 pain-in-the-neck compile errors is better than 100 hidden runtime bugs just waiting to cut your neck off.

  3. The Semicolon From Hell!
    Let me demonstrate the perils of the semicolon.

    // A macro to increment a counter, and wrap around to zero is a limit is reached.
    #define ADVANCE(x, wrap)    ((x) = ((x)+1)%(wrap));
     
    // Usage 1
    while (should_go_on)
        ADVANCE(i, 100);
     
    // Usage 2
    for ( ; should_go_on; ADVANCE(i, 100))
    {}
     
    // Usage 3
    while (should_go_on)
        p = ADVANCE(i, 100) + 100;

    As long as you stick to the first usage (i.e. as a statement,) you get away with your mistake (the spurious semicolon at the end of the macro definition.) However, usage 2 won’t compile. But this is a good thing, since you will know that you have an error in your macro (of course, if you’re a newbie in C++, it may take you quite a few minutes to figure this one out.)
    Usage 3 is where things get interesting. The code will compile (at most with a mysterious and seemingly unrelated warning,) but it won’t do what you think it does. That can be a bitch to track down.
    So, the moral of this story is: don’t put semicolons in macros!

  4. The Multiple Evaluations From Hell!
    #define SQR(x)    ((x) * (x))

    What happens when you evaluate the value of SQR(++a)? Does that seem alright to you? (By the way, any one who tells you a += b is equivalent with a = a + b is either a moron, or thinks you are a moron!)
    The lesson of this item is: don’t use macros as fast, generic functions! Use inline templates (which are even potentially faster (do you know when? :D )) Like this:

    template <typename T>
    inline const T & sqr (const T & x) {return x * x;}
  5. The Multiple Statements From Hell!
    The following macro deletes a pointer and sets it to 0, a very sensible thing to do nearly all the time.

    // This is not OK. Don't use this macro like this. Keep reading down this article!
    // Also note that I've not placed a semicolon at the end.
    #define SAFE_DELETE(ptr)  delete (x); (x) = 0
     
    // Usage 1
    char * s = new char [42 + 1];
    ...
    SAFE_DELETE(s);
     
    // Usage 2
    if (some_condition) SAFE_DELETE(s);

    But it doesn’t work, does it? I mean, usage 1 is OK, but you’ll wish you were never born when you have to stay up late into the night and debug the results of the second usage, won’t you? So, what do we do? I imagine everybody’s first response would be:

    // This is not OK, still.
    #define SAFE_DELETE(ptr)  {delete (x); (x) = 0;}
     
    // Usage 3
    if (some_condition)
        SAFE_DELETE(s);
    else
        doSomeWork (s);

    See the problem? No? The problem is in the semicolon before else. C++ doesn’t let you put a semicolon after an closing curly brace (’}') and before “else”. So what do we do? This is one of the solutions:

    // This is almost OK, and usable if you are not very picky.
    #define SAFE_DELETE(ptr)  do { delete (x); (x) = 0; } while (false)

    That’s right! We put the multiple statements inside a do/while block that is guaranteed to be executed only once! Brilliant, isn’t it? Well, I didn’t come up with it. I wish I could say that I though of it independently, but that’s not the case. I saw it in kernel code even before I had run into this problem! But the code didn’t say why it was used this way, and analyzing and discovering the purpose of this small piece of code was one of my biggest “Aha!” moments in C programming.
    So, we are good to go, right? Well, not quite. If you don’t care much about warnings the compiler gives off, you are good to go. But the above code results in a warning (only when you have turned the compiler warning level to the highest degree,) that the used condition is constant. Although the occasions for this warning are intentional most of the time (like here,) it may be the case that the compiler is warning us about a typo. Because of this, I don’t want to disable this warning (unlike those blasted 4996 warnings Visual C++ gives off like candy on Halloween, which I shut off with a wide and hysterical grin, while caressing my ax handle!)
    So what do we do? The best solution that occurs to me is like this:

    // We define a function that always returns false
    namespace __useless {
    inline bool i_am_false () {return false;}
    }
     
    // Now we use the above function instead of hard-coding the constant expression
    #define SAFE_DELETE(ptr)  do { delete (x); (x) = 0; } while (__useless::i_am_false())

    We trick the compiler here. The compiler is wise enough (or not smart enough) to give a warning no more, but any optimizer would optimize the overhead of the function call away completely.

  6. The “if” From Hell!
    Suppose we “optimize” the above SAFE_DELETE macro, to check whether the argument is NULL, and do nothing in that case.

    #define SAFE_DELETE(ptr)    if(ptr) delete (ptr), ((ptr) = 0)
    // Note that I've incorporated the comments from Hadi (comment 2) here, to make a point.
     
    // Usage 1
    if (some_condition)
        SAFE_DELETE (s);
    else
        return 0;

    Ouch! That hurts. I don’t think there’s anyone who doesn’t know this already, but in case there is (almost no shame in not knowing,) the “else” in the first usage will be the else clause for the “if” inside the macro! You are going to hate Dennis Ritchie after the first two hours of bewilderment over this (but of course, that would be out of frustration, and without logical cause!)
    You may be tempted to solve the problem like this:

    #define SAFE_DELETE(ptr)    if(ptr) {delete (ptr); (ptr) = 0;} else {}

    But don’t! Do this:

    #define SAFE_DELETE(ptr)    do { if(ptr) {delete (ptr); (ptr) = 0;} } while (__uselss::i_am_false())

    The moral? If you write “if” clauses in macros, be extra careful.

The above were only some of the pitfalls, but I can’t continue right now. Looking forward to your suggestions. Don’t be shy!

VN:F [1.0.8_357]
Rating: 10.0/10 (1 vote cast)

C++
code
updated

Comments (6)

Permalink

Unguaranteed Order of Pre-main Object Initialization in C++ - Any Solutions?

The C++ standard leaves the relative initialization order of global and static data undefined. The only thing that the compilers must guarantee is that all such data have been initialized before the invocation of main(). In any large and well-designed project, there are no or very few global objects. But static member data in classes are unavoidable in many occasions.
The unspecified and unguaranteed relative order of initialization of these objects can lead to undesirable effects. You could very well end up using objects that have not been initialized yet.
This is my problem. I’m in the design stage of a large library, and I want to know any thoughts or useful material you might have or have seen relevant to this problem. (This library is a game engine, by the way, and we will be delighted to have anyone with enthusiasm and technical expertise on board with us.)
One solution that comes to mind is doing all the initialization of static object in functions (for example, one per each class with static data members) and “registering” these functions and their relative priority at the static initialization time (before main()) but do not invoke them then. The only static object that is actually initialized pre-main is the object that we register these initialization functions to. At the beginning of main(), the said registrar object goes through its list of init functions, sorted by relative priority, and invokes them one by one. The static objects can register termination functions as well to be invoked at the termination of main. This way, the relative order is ensured and the initialization and termination are done pre-main (actually, only before all the objects initialized in main(), but after the start of main() itself,) and post-main, respectively.
The problems with this scheme are the verbosity of writing initialization/termination functions, and the fact that the static objects are constructed before main() anyway. We only re-initialize them. This can be costly, wrong or plain impossible, depending on the design of each specific class.
Has anyone got a better way? Any illumination?

VN:F [1.0.8_357]
Rating: 1.0/10 (1 vote cast)

C++
programming

Comments (1)

Permalink

C++: Fun With Precompiled Headers

Those of you who have worked on middle-sized to large projects in C++ (any more than 50000 lines of code) know that build time becomes a rather important factor in the development process. On any typical project, a full build time can very well exceed 10 minutes on a modern machine. Although there are many factors aside from mere line count (for example, heavy use of templates) affecting the exact build time, any amount of time more than a few seconds you spend staring at your monitor waiting for a build to finish is hardly pleasant.

On really large projects, some very drastic measures are taken to mitigate the problem of build times. These may include distributed (even grid-based) build systems or dedicated build machines that automatically build the project after each code update to the project repository or at designated intervals. But for any smallish company or team, such measures may not be applicable. Using Pre-Compiled Headers (or PCH for short) can be an attractive solution.

First let me go over some basic stuff. As you know, a C++ compiler only accepts individual C++ code files as input (called a compiland (like operand!) sometimes.) Your project might easily have a couple of hundred (to a few thousand) source files (not counting the header files) but each must be fed through the compiler to produce an object file individually. The next step would be to run a linker (or alternately a “librarian”) to link those object files together and produce an executable (or a library) file.

We all know that all the “.cpp” (or “.cc” or whatever) files are compiled separately. The obvious result is that the header files that each source file includes must be read and parsed and incorporated into the object file once for each and every source file. This opens up an opportunity for greatly saving on compile time. You see, a typical source code file is usually between 200 to 2000 lines of code itself, but it very often includes tens of thousands of other code in form of included header files. It’s really easy to see for yourself. Just pass your source code file that includes a handful of STL headers to the compiler and tell it only to “preprocess” the code (check your compiler’s documentation.) Look at the resultant file. That’s what the poor compiler receives for each cimpiland.

If you use template classes and functions heavily, the situation becomes even more difficult. Because each template class will be specialized by the compiler for each usage throughout the code. That is, you write a 500-line template class, and use it with 20 different types as template arguments. That’s 10000 lines of code right there, not to mention the fact that the source is now much more complex for the compiler to optimize and generate target code from. Let’s face it, templates are great facilities for generic programming, cleaner design, better performance and general wizardry, but they’re no friend of the compiler’s!

Anyway, suppose that you include <map>, <fstream> and <algorithm> headers (from STL) in almost all of your source code files. Since each file is passed to a separate instance of the compiler, no information is interchanged between the instances and the compiler reads, parses, generates code from and optimizes all the three header files for each source file. This is clearly superfluous. The opportunity I mentioned is right here. If you could somehow do the many steps necessary for processing these files (or at least some of the steps) and store the results and the state of the compiler somewhere (in a file, for example) you wouldn’t have to do that for every source file. You would just read that intermediate state file almost directly into memory and save a lot of time.

This is precisely what using pre-compiled headers is. There are some restrictions however. The headers you want to compile into a PCH file have to be exactly the same and they have to be included in every source file and in exactly the same order. This might mean that some of your source files may include headers that they don’t actually need, but this seldom causes any problem. Also, it is essential that the headers you want to pre-compile be included as exactly the first statements of each source file. Because C++ code (specially preprocessor code) can affect the way other included header files (that are included further in the file) behave, there must not be any code before the inclusion of the headers intended for pre-compilation or that code too, becomes part of the PCH.

One more thing that is necessary is to tell the compiler to stop putting headers into the PCH at some point. This is achieved by putting a “#pragma hdrstop” after all the headers that we intend to be included in the PCH file, and before anything else.

There’s a convenient way to manage all this. We can put all the inclusion statements of all the include files we want to go into the PCH file, along with the pragma directive in a specifically designated header file (let’s call it “PCH.h“) and include this file at the very top of each and every source file (remember: only source files, not other header files.) This ensures that the header files and their order is exactly consistent across all files and removes the need for much duplication of #include statements that might lead to much grief. (As a side note: Don’t Repeat Yourself!)

Now, you tell the compiler to create the PCH, and use it throughout the build. Therefore, you have to change the compile command for exactly one of your source files to create the PCH while it’s being compiled (and put this command at the beginning of the list of files to be compiled in your Makefile or whatever) and change the compile command of all the other source files to only use this newly created PCH file.

Since the precompiled header can become a very big file (many tens or even hundreds of mebi-bytes) and it has to be rebuilt every time either the headers included in it are changed (a genuine requirement) or the source file used to create it changes (imposed, because the code in that file will not be included in the PCH anyway) we can create a dedicated source file just for the purpose of PCH creation. This (e.g.) “PCH.cpp file will be empty except for a single #include <PCH.h> statement. This way, this source file never changes and one cause (however minor) for rebuilding of PCH is eliminated.

For those of you who use IDEs and Microsoft Visual Studio in particular (like myself) here’s how you do it in the VS IDE. First go on and create the said “PCH.h” and “PCH.cpp” files above. Remember to include “PCH.h” in every source file at the very top and remember to add “PCH.cpp” to your project. Also very important is that you must remove all the inclusion statements of the files already included in the PCH from each and every source and header file in your project (it’s best to #define them out (actually #if defined them out,) in case this didn’t work out for you and you wanted them back!

OK. Now you have to tell VS to tell VC that you’re going to use PCH. Go to Project->Properties and in that dialog (while making sure “All Configurations” is selected in the “Configuration” combo box on the top left) Configuration Properties->C/C++->Precompiled Headers. Change the value of “Create/Use Precompiled Header” to “Use…” (with command-line switch of “/Yu”) and change the file name in “Create/Use PCH Through File” to whatever the name of your header is (”PCH.h” in our example) and don’t forget any path prefix it might have (you shouldn’t give an absolute path here, but a path relative to one of your include search path directories or your source file directory.)

This has the effect of setting the compile commands for all your source files to use PCH. But someone has to create it first! Find (in “Solution Explorer” window,) the source file you designated to create the PCH (for example “PCH.cpp”) and (right-click on it and) open it’s “Properties” dialog. While again making sure “All Configurations” is selected (as opposed to just “Debug” or “Release” or whatever), find your way to the same place as before (PCH settings.) These are the build options just for our selected file. Only change the “Create/Use Precompiled Header” to “Create…” (instead of “Use…”) and your all set. You should not change the name of the files (neither the header file nor the resulting PCH file) in this dialog.

Now make a full rebuild of the project. If you’ve done it right, and I haven’t forgotten anything important, and your project is big enough, with this rebuild you should see a great speed up. I have seen build times go from 20-25 minutes to 5 minutes and from 8-9 minutes to 1:50-2 minutes instantly.

I suggest you time your builds before and after the use of PCH (in VS2005, go to Tools, Options…, Projects and Solutions, VC++ Project Settings, Build Timing and set it to “Yes”.)

One thing to note. Sometimes, if your project is large enough, the VC compiler will run out of memory and terminate while building the PCH. In that case, you should append a “/ZmXXX” to all your compile commands, where XXX is the amount of memory in some weird scale and unit. Check the compiler documentation (or follow the build error you get when you run into this problem.) In order to do this inside the IDE, go to you project properties dialog, make sure “All Configurations” is selected, go to “C/C++”, “Command Line” and add the (e.g.) “Zm150″ to the (probably) empty box of “Additional Options”. Experiment with the value a bit to find a suitable value that doesn’t exhaust all your available memory and still allows a build.

I hope this mini-guide comes handy to someone someday! Please let me know of any errors I’ve made, or any omissions or inaccuracies.

VN:F [1.0.8_357]
Rating: 1.0/10 (1 vote cast)

C++
programming

Comments (8)

Permalink

KOPCS Distribution 1371

This is the long overdue package (and “ymeta” file,) containing KOPCS source code (verion 1.0.0 (codenamed Rincewind) build 1371.) The package also contains pre-built binaries mostly for Windows, but “Zero” is provided for 32-bit x86 Linux as well.
The package contains KOPCS (plus less-than-minimal documentation,) JFKOPCS scripts, yCrypto (plus documentation,) Zero, the web page templates, some tests and VS2005 project files and Makefiles.
There’s no guarantee that anything in it works or even compiles. Do not trust anything you hear or receive from me! The only external dependency is MySQL (preferably 4.x or 5.x, but 3.2x may work) to build and run and Apache 2.0.x or 2.2.x to run it.
There’s no setup guide whatsoever. Good luck!
BTW, I’m going to setup a subversion repository for KOPCS soon. The only problem I have is migrating from the existing local CVS (on Mike) to a remote SVN on yaserzt.com.
UPDATE 2007-11-04: The authors of KOPCS are (in no particular order) Ehsan Adeli Mosabbeb, B. Maryam Elahi and myself. The source code has been released with their expressed permission. An implementation of the SHA-256 in JavaScript language by Angel Marin has been used. Please refer to the file “webfiles/media/sha256.js” in the distro for more information.
I guess a quick note about licensing is in order. All the work done for KOPCS by the above-mentioned authors are released under the terms of the Lesser General Public License version 3 (a.k.a. LGPLv3) with the exception of the IAUM-CCC website templates and the JavaScript code used in it, which are under the terms of the General Public License version 3. The website templates include and is limited to any file with the extension of “.htmltemp”, “.js”, “.css”, “.png” and “.ico”. Note that KOPCS is released AS IS in the minuscule hope that it would be useful, but without any guarantee (even implied) that it will be suitable for any purpose. That means, if KOPCS destroyed your hard drives or burned down your house, it’s your fault not ours!

VN:F [1.0.8_357]
Rating: 1.0/10 (1 vote cast)

C++
KOPCS
code
programming

Comments (4)

Permalink

C++: Fun With Comments

There’s much fun to be had with C++ comments, and a lot of seriously usable tricks there as well. Of course, most of programmers already know all I could tell about the subject, but nonetheless, I think I’ll take a shot at bringing all the techniques I think might be useful together, and I might be able to use a few possible tricks that a possible visitor would possibly leave on this post!
The first thing any programmer has to realize about comments is that (as their name suggests)

Comments are not the code that the compiler doesn’t see, but the sentences that a human would read.

Write comments (and code in general) for another human (or you yourself) to read. This generally means you should generally avoid too clever constructs that have no other advantage. I say it again: Write code for other humans to read, not the compiler to compile.
You can use special comments and tools like doxygen to generate useful, beautiful, always-up-to-date and comprehensive documentation of your source codes automatically, with little extra work (e.g. with putting a line with three slashes (”///“) at the beginning and describing the purpose of a function before its prototype.) These kinds of tools make you appreciate the value of comments!
My first advice is never use “//” or “/*” to comment out a piece of code. Those characters are reserved for “comments”, i.e for writing descriptions of your code! Always put another character (or sequence of characters) after them, and use different characters to distinguish the different situations in which you’ve commented out the code. For example, use “//0” and “/*0” for code that you suspect is incorrect, use “//1” and “/*1” for test code, and so on and so forth. Keep in mind that these are only suggestions. Any system you opt to use, must be documented somewhere. Write 10 lines to describe the meaning and connotation of the 10 different types of comments you use. Don’t take this lightly! As time goes by and you write more code, you’ll accumulate these rules and split or merge them, but your commenting rules become more comprehensive, more concise and more useful.
Anyway, suppose you want to comment a multi-line piece of code. Always put the comment openning and closing on a line by themselves. No code on those lines! Also, use “//*/” for the closing marker (instead of just “*/“.) This way, you can uncomment and recomment that part with only a single character; a ‘/‘ that you add to or remove from the beginning of the openning marker. Look at snippets 1 and 2.
There are times that you want to switch between commenting two parts of a single line. In these situations, you can put “/**” before the first part, put “/*/” between the two parts and “/**/” after the second part. Like snippets 3 and 4, you can then switch between the first part being commented out and the second one by adding a single ‘/‘ after the comment before the first part. (Also note the parsing/formatting bug of jEdit on line 18!)
You can also do it in the slightly prettier way that snippets 5 and 6 demonstrate (I really think so!) but only if you want to switch between two multi-line segments of code.
Commenting large blocks with “/*” and “*/” has a major problem. The commented blocks don’t nest. For this reason, I suggest the cleaner method of using “#if 0“, “#else” and “#endif” blocks (snippets 7 and 8, but they lack the coloring.) This way, not only you can nest commented out blocks inside of each other and enable/disable them individually just changing the ‘0‘ to ‘1‘ (provided the outer blocks are not disabled) but also you can comment the commented-outness(!) of these peices, and you can use preprocessor macros instead of just ‘0‘ to be able to switch these segments on and off from elsewhere. The only problem is that many editors and IDEs don’t process preprocessor directives and they won’t colorify the disabled parts as inactive.
In your “comment” comments, you can use well-recognized keywords like “NOTE“, “WARNING“, “TODO” and “FIXME” to make their meanings more apparent and to searching for them easier. Just remember to use them neatly and consistently.
If you have more ideas for using comments, I’d be happy to hear about them and to include them here. By the way, anybody has a clean and pretty way of switching (commenting/uncommenting) among three or more segments of code?

   1://{Snippet 1}
   2:/*0
   3:    for (unsigned i = 0; i < v.size(); ++i)
   4:        swap (v[i], v[v.size() - 1 - i]);
   5://*/
   6:
   7://{Snippet 2}
   8://*0
   9:    for (unsigned i = 0; i < v.size(); ++i)
  10:        swap (v[i], v[v.size() - 1 - i]);
  11://*/
  12:
  13://{Snippet 3}
  14:    for (unsigned i = 0; i < /**/ v.size() /*/ v.size() / 2 /**/; ++i)
  15:        swap (v[i], v[v.size() - 1 - i]);
  16:        
  17://{Snippet 4}
  18:    for (unsigned i = 0; i < /** v.size() /*/ v.size() / 2 /**/; ++i)
  19:        swap (v[i], v[v.size() - 1 - i]);
  20:        
  21://{Snippet 5}
  22:/*0
  23:    for (unsigned i = 0; i < v.size(); ++i)
  24:        swap (v[i], v[v.size() - 1 - i]);
  25:/*/
  26:    for (unsigned i = 0; i < v.size() / 2; ++i)
  27:        swap (v[i], v[v.size() - 1 - i]);
  28://*/
  29:        
  30://{Snippet 6}
  31://*0
  32:    for (unsigned i = 0; i < v.size(); ++i)
  33:        swap (v[i], v[v.size() - 1 - i]);
  34:/*/
  35:    for (unsigned i = 0; i < v.size() / 2; ++i)
  36:        swap (v[i], v[v.size() - 1 - i]);
  37://*/
  38:        
  39://{Snippet 7}
  40:#if 0
  41:    for (unsigned i = 0; i < v.size(); ++i)
  42:        swap (v[i], v[v.size() - 1 - i]);
  43:#else
  44:    for (unsigned i = 0; i < v.size() / 2; ++i)
  45:        swap (v[i], v[v.size() - 1 - i]);
  46:#endif
  47:        
  48://{Snippet 8}
  49:#if 1
  50:    for (unsigned i = 0; i < v.size(); ++i)
  51:        swap (v[i], v[v.size() - 1 - i]);
  52:#else
  53:    for (unsigned i = 0; i < v.size() / 2; ++i)
  54:        swap (v[i], v[v.size() - 1 - i]);
  55:#endif

UPDATE:I was wrong about the parsing/formatting bug in jEdit I mentioned above. That’s a Doxygen comment and jEdit handles it correctly. Oops!

VN:F [1.0.8_357]
Rating: 1.0/10 (1 vote cast)

C++
code
programming

Comments (0)

Permalink