This is a good book as it does a good job covering the different sources of software insecurities:
On the last point, the authors know well the topic. If you are using cryptography to protect something in your software but just store the private key in a global variable then you are helping tremendously the job of hackers as all they will have to do is look into your executable binary to search for something that looks like a key. A security measure is as strong as its weakest element and no hacker is foolish enough to attack a cryptographic algorithm that is proven strong. Even if you store the key in a secure place, all that is needed to retrieve the key is to perform a memory dump at the right time just before the software use the key. At least, you can make hackers job harder as there is nothing you can do to make your software 100% safe against hacker if the software is valuable enough to motivate them to hack your software. All you can do by improving your software security is to buy you some time before your software is hacked. All that to say that there is no bullet proof solution against hackers but the book gives solid leads to improve software security in that aspect.
In this book, there is a strong emphasis on Microsoft security technologies. The Windows Crypto API and the Microsoft OSes privileges API are described in length. If you develop on Windows and want to make your software more secure then this is an excellent book for you. If you develop on another platform, there is still something for you in this book as there are a lot of code snippets that are platform independent to improve software security such as input validation for file names to protect yourself against canonization bugs.
This is a very good book about software security but I do not recommend it simply because there is a new edition of it.
The name has been coined by Bjarne Stroustrup and is using the property that an object constructor and destructor will always be called at the beginning of the object existence and when it will goes out of scope. This is guaranteed by the language itself and the object will be destructed no matter how it goes out of scope. It could be by exiting a function or when the stack is unrolled by an exception been propagated out of the stack.
The RAII consists of encapsulating a resource (be it a file handle, a lock or a pointer on an object allocated on the heap) in a class. The resource acquisition will be performed in the constructor and then the C++ rules governing the lifetime of an object will take care of releasing the resource by calling the class destructor. It is to support that technique that the class template auto_ptr has been included in the standard library.
The technique has 2 purposes:
1- Simplifying code
Traditionally, it has been very error-prone to perform resource management from a function having many exit points. Suppose the following function:
void foo() { // Acquire resource A // Do some processing if( error ) { // release resource A return; } // Acquire resource B if( !B ) { // release resource A return; } // Do some processing // Release resource A // Do some more processing // And finally, release resource B return; }
Now imagine that this small game of resources tracking spans over more than a hundred lines of code and that you have dozen of resources. This is a waste of energy and chances are that there will be a resource leak in this type of code. If it is not today, it can be during the next maintenance of the function in few months or years where you will need to add another exit point in the middle of that type of function. The best way to handle this is with RAII. Once you acquire the resources, you can forget about them as they will be automatically released when the code will exit the function. As an added bonus, it will simplify the code as all the statements for releasing the resources are not needed anymore.
2- Make it easier to achieve exception safety in functions and particularly in constructors.
When an exception is thrown from a constructor of a class acquiring resources, the hard and error prone way to make sure that no resource are leaking is to place the constructor code in a try block and to manually release the acquired resource in a catch all block before rethrowing the intercepted exception. The C++ language specify that in the event of an exception during the construction, the compiler will generete code to destroy constructed base classes and data members that are objects (raw pointers on dynamically allocated memory does not count) before letting the exception escape from the constructor. Hence again, if you used RAII to encapsulate resource acquired during construction in objects, you will not need to worry about releasing them as the compiler will handle this for you.
One detail worth mentioning is the RAII is not an applicable idiom in some other OO programming languages. For instance, in Java because of its garbage collector, there is no guarantee from the language when objects will be destructed. It will just happen eventually after objects goes out of scope once the garbage collector recuperates the unused objects.
Pipelined processors do not like conditional branches because when conditional branch is entering in the pipeline, the processor does not know yet what will be the condition outcome but it needs to continue to fill the pipeline with new instructions. In that situation the processor will try to predict what will be the condition outcome and start filling the pipeline from its prediction. This is very costly performance wise when the processor mispredicts the condition outcome. When that happens, the processor has to flush the pipeline content and start filling it again from the branch point.
The conditional branch prediction module has 2 components. There is the branch outcome cache that will help the processor to remember what was the outcome of branches that it has encountered recently and a static branch prediction algorithm.
The static branch algorithm is very simple:
If you read the Intel processor optimization guide, few simple guidelines are easy to apply:
1. Eliminate branches
Some conditional branches are simply useless as whether they are taken or not, it will not make any differences on the end result. 2 examples of these are:
if( i != 0 ) i = 0;
or
if( ptr != NULL ) { delete ptr; ptr = NULL; }
should be changed to:
i = 0;
and
delete ptr;
ptr = NULL;
It is faster to reassign the same value to a variable than conditionally assign it. The operator delete
and the function free()
already contain safeguards against NULL
pointers and it should be quite exceptional that they are called anyway with NULL
pointers.
2. Refactor if statement conditions to be true most of the time.
Here is an example:
if(error) { // exceptional error handling } else { // normal operation }
would be faster written like:
if(!error) { // normal operation } else { // exceptional error handling }
To conclude, these guidelines are specifically for Intel processors but since the static branch prediction algorithm used by Intel processors is widely used by other pipelined processors (PowerPC is one of them), applying them on other platforms should be beneficial as well. Also, if you are looking for other optimization techniques, you can consult these sources.
I have done pthread programming for a while and read a couple of books on the topic too but nothing have prepared me to the undefined behavior that I have discovered the hard way.
The POSIX standard states that when the main thread exits the process, the remaining threads will be automatically terminated. What the standard does not specify is in which order the different process cleanup will occur hence if you leave the process without terminating yourself the threads, you will get undefined behavior. In my case, it was a segmentation fault.
The undefined behavior is real especially if this is a C++ program because part of the termination cleanup, there is the destruction of the program global objects. If your threads are still running and happen to use global objects, this is a sure way to a segmentation fault.
Even in fixing the problem, I have learned again something new about pthreads programming. To fix my problem, I just sent to myself the SIGINT signal that initiates the correct termination. In my first attempt, I have replaced my exit()
function call with raise(SIGINT)
which I have read in my UNIX programming textbook was the equivalent to kill(getpid(), SIGINT)
but by doing so, the signal was never received. After some investigation, I have found in a book, that in a multithread program, raise(SIGINT)
was equivalent to pthread_kill(pthread_self(),SIGINT)
. In my case, calling raise was doing nothing because the signal was blocked in the thread from where the call was done. Everything finally worked fine when I replaced the raise call with kill(getpid(), SIGINT)
.
This is an advice that can be found in many books such as:
C++ Coding Standards, Exceptional C++, More Effective C++ or The C++ Standard Library
However, despite the abundance of literature giving this advice and explaining why, a lot of people are not aware of this. So if you are one of these persons and you are someone who is spending more time browsing the web than reading books and you have found this blog, this is for you.
At first look, statements like
++i; i++;
seem equivalent but you have to remember that if i
is an object, the increment operator is implemented with a function. Seeing the form of typical operator functions implementation should explain everything:
// Prefix version T& T::operator++() { //Perform increment return *this; // Return a reference on this } // Postfix version T T::operator++(int) { T res(*this); // Make a copy of the current value ++*this; // Call the prefix version return res; // Return the value by result }
So, as you can see, most of the time the postfix increment operator is implemented in terms of the prefix one so even if you call the postfix operator, you will end up calling the prefix operator function anyway. The rest is just overhead:
operator++()
is not inlineYou'll notice that at the third point, I used 'might'. If you have a good compiler, it might be able to get rid of the construction of the return value by using a technique called the Return Value Optimization (RVO). Most compilers are able to pull off that optimization with an unnamed object (temporary object) like:
return T;
If a return statement is returning an automatic variable (local variable) declared before the return statement as it is done in the operator++(int)
function, a lot fewer compilers are able to apply the RVO. Those who are able are said to have named RVO (NRVO). Visual C++ has it only since version 2005 according to this blog entry. GCC supports it since version 3.1 according to this Boost mailing list archive entry.
To conclude, it should now be obvious that unless you absolutely need the postfix increment semantic, you should use the prefix version. This should represents 99% of the increments in a program since usually, they stand alone in their own statement and the return value is just not used at all. This is usually what happens in code using STL containers iterators. One could argue that it does not make a perceptable difference performance wise in a program. Maybe but why choosing the slowest option when both ways are equally easy to write? Herb Sutter and Andrei Alexandrescu think the same and they give the excellent advice (Don't pessimize prematurely) in their book C++ Coding Standards.
Before clearing or destructing a STL container containing dynamically allocated pointers, it is important to delete the pointers or else, you are going to leak memory and resources (See item 7 in Effective STL). The usual way to this is:
for( vector<MyClass*>::iterator it = v.begin(), e = v.end(); it != e; ++it ) { delete *it; } v.clear();
There is a small twist with sets. This code would be fine with a set using its default compare function but since sorting pointers with their values is not very useful, most of the time, such containers are configured with a custom compare function that dereference the pointers to perform its comparison. The standard does not specify which set methods use the compare function and which are not. So it is looking for trouble to free the memory and keep the pointers on it in the set and at best your set will be in an invalid state.
The easy way is to store boost::smart_ptr<MyClass*>
into the set. All you have to do is to clear the set and the smart pointers will take care of deallocating the memory. My opinion, however, is that this solution is like using a machine gun to kill a mosquito. The real purpose of smart pointers is for dealing with situations where the pointers ownership is fuzzy. If you know that it is safe without any doubt to delete the pointers in your container when you want to clear it, you should not be using smart pointers.
Another option is to use boost::ptr_set
but since I am not very familiar with this class, this is not something I will recommend.
The best solution that I have seen is simply doing this:
typedef std::set<MyClass*, CompFuncThatDerefencePointers> MySet; for( MySet::iterator it = s.begin(), e = s.end(); it != e; ) { MyClass *p = *it; s.erase(it++); delete p; }
There are 2 more details that I want to discuss. Some STL containers (such as set
and map
) erase()
method signature is
void erase(iterator it);
and some other containers (list
and vector
) have
iterator erase(iterator it);
The second signature makes sense for containers that upon insertion or removal of elements invalidates all iterators on it but I have no idea why list has its erase returning an iterator. If you think that you might switch from a list to an associative container, you might want to erase elements from the list with
l.erase(iter++);
to keep your code compatible with the associative containers interface. As I am writing, I think that the STL designers decided to make the list erase signature compatible with the vector erase
because they considered that this was the most likely switch if you had to change your container strategy.
The other important point that I wanted to mention is that my recommendation to explicitly clear the pointers rather than using boost::smart_ptr
assumes that your container is a data member of a class and that you are using the RAII idiom. That is that you are deleting the container elements memory in the class destructor. This is to be sure that your code is exception-safe. If your container is an automatic variable in a function, then this might be an appropriate situation to use boost::smart_ptr
because if you do not and an exception is thrown before your container clearing code is executed, you will leak memory.
In the book The C++ Programming language from Bjarne Stroustrup, you can read in section 5.7 (Structures):
The size of an object of a structure type is not necessarily the sum of the sizes of its members. This is because many machines require objects of certain types to be allocated on architecture dependant boundaries or handle such objects much more efficiently if they are. For example, integers are often allocated on word boundaries. On such machines, objects are said to have to be aligned properly. This leads to "holes" in the structures...You can minimize wasted space by simply ordering members by size (largest member first).
As an example, on my platform if I write:
struct MyPOD1 { bool a; int b; bool c int d; }; struct MyPOD2 { int b; int d; bool a; bool c; };
sizeof(MyPOD1)
is 16 and sizeof(MyPOD2)
is 12. which means that 4 bytes are wasted by the MyPOD1 layout. Bjarne continues by adding that you should prefer readability over memory usage optimization but in my opinion taking the habit of always placing 1 byte variables such as bools and chars at the end of a class data members declaration can hardly obfuscate the code especially if the class encapsulation is tight.
Now that the demonstration that by just reordering data members around in a class declaration can save space has been done, let me explain to you the advantages of saving few bytes. Just imagine that you have a std::vector<MyPOD2>
of 25K elements. You just saved 100KB of space to your program for free and since more elements will fit in the processor cache which should make the vector traversal faster.
I recommend taking this habit because it is easy to do and once you get used to do it, it will become an automatism and you will get the best performance from your data structures without having to stop and think about how you could optimize them before you need to.
The hardware aspect of this webcam is impeccable. The image and the sound quality are very good. What is spoiling the package is the bad quality software bundled with this webcam that can bring Windows to become unstable. Casual computer users might never encounter the problem if they just open few programs. For the problem to occur, you have to spawn many processes. Examples of such activities are execution of batch files or using cygwin. The symptom of an unstable system is a dialog box with the following message every time that you start a new program:
Dwwin.exe:
The instruction '0x7c883f9c' referenced memory at '0x7c883f9c'. The memory could not be 'written'.
When that happens, the only thing you can do is reboot your PC. I have been months living with this problem without knowing what was causing it. For this reason, I am very unhappy with this product and I strongly discourage anyone to purchase a Logitech webcam as I think that almost, if not all, Logitech webcams are bundled with the same drivers. After this warning, if you still consider purchasing a Logitech webcam, I can tell you that there is a work around. You can turn off the Logitech Process Monitor. To do so, you go in the services panel that you can find in the 'Administrative tools' menu, find the Logitech service and stop it and set its startup type to manual to be sure that it will never run again on your system.
In my opinion, this book is better than Pthreads Programming because it goes way beyond just presenting the pthreads API. One critic I had on all the other multithreading books that I have read is that they are not covering issues with multithread programs on a SMP system. This book is actually discussing some of these issues on several pages! Beside this quality, it also covers high-level design patterns on how you can use threads such as pipelines, work crew and client/server. There is also a chapter showing how to program with thread cancellation and a section explaining how to create new synchronization objects from the primitives.
This brings me to the only problem that I can think of this book: its age. It is not totally up to date. Learning how you can build new synchronization objects by itself is a very interesting exercise but the problem is that the new synchronization objects built are the barrier and the read/write lock which have been added to the pthreads API since the book publication. Also, except for a small section describing the futur of pthreads, the newest additions to the pthread API are not described.
This book has been recently recommended to me by Amazon based on my previous purchase habits and I decided to go take a look at its description. At first, I was little bit skeptic about the value of a book published in 1993 and prepared with Word for Windows 2.0 because software programming has changed a lot since then! However, it was a very low risk purchase because of its very low price tag so I decided to give it a try and I have been pleasantly surprised!
This book is the proof that that there are few things in programming that are timeless. Errors of the past still occur today. The programming language used for the examples is C but what is taught is also applicable to C++ programming as well. Topics discussed in the book are: assertions, integrity checks, stepping through code with a debugger, how to not design interfaces that are error prone, avoid language features that are error prone and finally the author conclude his book by describing the attitude that a programmer should have. Among other things, a programmer should prioritize safe code before micro-optimizations. All these concepts are written in a style easy to understand filled with anecdotes that make this book a pleasant read.
To conclude, I have not been blown away by the content of this book but I have learn one thing or two and I am glad that I have read it especially with its very low price tag.
Which is better
void f(int &a);
or
void f(int *a);
?
Once compiled, there should not be any difference between the 2 versions as references are most likely implemented with pointers under the compiler hood. The main difference between passing a pointer to a function vs a reference is that with the reference you are sure that the reference points to a valid object where as with pointers you could pass a NULL pointer.
Hence, if a NULL pointer is not a valid value for a function, you can enforce that fact by passing a reference. Some people argue that it is possible to have dangling references by doing:
int &f() { int a; a = 5; return a; } int main(int argc, char *argv) { int &r = f(); return 0; }
or
int main(int argc, char *argv) { int *p = new int(5); int &r = *p; delete p; return 0; }
but I consider these cases pathological and my opinion is that references are safer than pointers because:
With these, it should be much harder to have *unintentionally* dangling references than having uninitialized pointers especially if you do not do the newbie mistake of returning a reference to a local variable. My C++ debugging experience has led to me to fix plenty of pointer problems but I have never seen until now a dangling reference problem in real code.
Also, Scott Meyers, in his book More Effective C++ (item 1: Distinguish between pointers and references), goes in the same way about this issue.
Jason T. Roff, author of many books including ADO : Activex Data Objects, visited my blog and left a comment in the blog entry reviewing his book.
I am quite happy as this is the first time that I am aware that one of the authors of the books that I reviewed actually read the review of his book. I have invited Bjarne Stroustrup to visit this blog when I have reported to him the bug found in the latest edition of his book 'The C++ Programming language' but he is a very busy man and I have not received any feedback whether he came here or not.
I just want to say that if you happen to be an author of one of the books that I have reviewed, your feedback is highly appreciated!
I have writen a new tutorial that presents an example on how to incorporate CFixeAlloc optimization into existing MFC software.
You can read it here and leave comments on it here.
I just published the second part of the serie on C programs refactoring in C++. Here is the introduction of this tutorial:
In the first part of the serie, I presented guidelines that needs to be followed when someone wish to use C++ from C programs. In an ideal world, the old C programs that you want to port to C++ should be rewritten completely. However in the real world, due to economical constraints, this is usually impossible and a more gradual approach must be adopted. During the transition period, to maximize the benefits of using C++ and to not end up with having a program consisting of just a bunch of C interfaces with C++ implementations, you can identify some patterns in the C program and refactor them appropriately. By having gone through the exercise myself, I am presenting the techniques that I have discovered and I will be discussing the benefits and the potential pitfalls of these refactoring patterns.
You can read the rest here.
I have written a new tutorial available on my website. Here is a small quote from the introduction that describes what it is about:
In this tutorial, I will introduce the simple guidelines and pitfalls to avoid when using C++ in C programs. The second part will continue by presenting higher level patterns to leverage the good software architecture patterns that C++ language facilities encourage into C programs.
You can read the rest here.
This is an acronym that means "substitution-failure-is-not-an-error" and it is used in the context of template functions overloading. When the compiler evaluates each overloaded template functions, it will not emit an error if by using the template parameter on one of the potential candidate function would generate an error. The compiler will just discard that function from the list of potential candidates. It is a powerful construction that allows metaprogramming as you can evaluate expressions at compile-time. Here is an example from the book C++ templates:
template<typename T> class IsClassT { private: typedef char One; typedef struct { char a[2]; } Two; template<typename C> static One test(int C::*); // Will be chosen if T is anything except a class. template<typename C> static Two test(...); public: enum { Yes = sizeof(IsClassT<T>::template test<T>(0)) == 1 }; enum { No = !Yes }; };
If T is a class, IsClassT<T>::Yes
will be true because the first test()
function will be chosen by the compiler. From the C++ templates book:
overload resolution prefers the conversion from zero to a null pointer constant over binding an argument to an ellipsis parameter (ellipsis parameters are the weakest kind of binding from an overload resolution perspective).
There is one subtle detail that is important enough to mention it. It is the usage of the template
keyword at the Yes enumeration declaration. The reason behind the need for using the keyword is similar to why you sometime need to use the keyword typename.
It is because of template specialization, the compiler has no clue what the dependent name "test" is. Without explicit indication with the keyword template
, it is interpreting "<" and ">" as "greater than" and "lower than" logical operators.
Maybe you were already using the principle without knowing its name but now next time you see SFINAE in a C++ forum, you will know what they are talking about.
This one has annoyed me for a while until I found the answer as pre STL stack classes used to have a pop()
function that was popping the element and returning it to the user. I was finding it conveniant because everytime I wanted to access the top element, I also wanted to pop out the element of the stack so why STL containers is forcing its users to perform this common operation with 2 operations?
In 'The C++ Programming Language' book, Bjarne Stroustrup has this to say about pop_back:
Note that
pop_back()
does not return a value. It just pops, and if we want to know what was on the top of the stack before pop, we must look. This happens not to be my favorite style of stack, but it's arguably more efficient and it's the standard.
I wish that he took the time to explain his position about why it is more efficient for pop_back()
to not return the element but I only understand why it was done like that by reading the book Exceptionnal C++ from Herb Sutter.
If you are using a STL container to store pointers, the performance argument disapear but if you store objects, all front()
is returning is a reference to the top element and if pop_front()
would return the top element, it would be by value and the copy constructor and the assignement operator would be involved. This is the performance argument that by having to call these 2 functions, it is adding overhead.
However, I suspect that this is not the main reason to have separated the 2 operations. Probably that the main reason is for exception safety garantee that the STL containers provide. Since, one requirement that STL impose on its users that contained objects destructors cannot throw exceptions, pop_front()
can provide a no throw garantee. It could not if it had to return the top element because if the copy constructor or the assignment operator was throwing an exception, the element would be lost forever. In contrast, when an exception is thrown while assigning front()
result, if you can cope with the exception, the element is not lost because it is still in the container.
One usage of them commonly demonstrated in C++ Templates textbooks such as C++ Templates is when you want to control the maximum capacity of a container like this:
template< typename T, int MAXSIZE > class stack { ... private: T m_array[MAXSIZE]; };
I have found another very useful property of integral constant template parameters. You can define a class template with an integral constant template parameter and not use it at all in the declaration:
template<int i> class Unique { public: static int var; }; template<int i> int Unique<i>::var;
The property of this template is that a distinct var variable will be created for each instantiation of the template:
Unique<1234>::var = 1; Unique<0>::var = 2;
and so on. By itself, it is more or less useful but imagine that you are dealing with a function registering a callback function that does not let you provide a parameter that will be passed to the callback function but your callback needs to access variables and you must provide more than 1 callback function and each of them needs to access its own set of variables. You could do it by hand by writing x different callbacks and create x sets of variables with different names but by doing that, you would be polluting your namespace and that would be a very long task for nothing. Instead, a class template with an integral constant parameter is the right tool for this situation:
template<int i> class CB { public: static void SetCBParams(int x1, int x2) { m_x1 = x1; m_x2 = x2; } static void CBFunc(); private: static int m_x1; static int m_x2; }; template<int i> int CB<i>::m_x1; template<int i> int CB<i>::m_x2;
and then
CB<1>::SetParam(1,2); registerCB(&CB<1>::CBFunc); CB<2>::SetParam(3,4); registerCB(&CB<2>::CBFunc); ...
Sometimes efficient memory management is needed and to accommodate that need, the C++ language provides the placement new operator to let the user specify the location where an object is going to be instantiated. When the placement new operator is used, the user must then explicitly call the destructor.
This is all fine but I have been wondering what happens when the placement new operator is used in conjunction with templates such as in the std::vector container and when the template parameter is a scalar built-in type that obviously does not have a destructor.
I have found out that the C++ standard committee envisaged the situation and has included specification of what a compiler must do in such situation. I do not have a copy of the standard text but the section 5.2.4 (Pseudo destructor call) states that the expression p->~T()
becomes a pseudo destructor call for a built-in pointer type, which does nothing.
Here is a small program that I have successfully compiled to verify that pseudo destruction works fine:
#include <iostream>
// The header file containing the declaration of the placement new operator
// according to 'The C++ Programming Language' book (section 10.4.11) but it
// compiles fine without. It must be because it is included from <iostream>
#include <new>
class TestClass { public: TestClass() : m_x(3) {} ~TestClass() { std::cout << "TestClass destructor called" << std::endl; } void print() const { std::cout << "Hello " << m_x << std::endl; } private: int m_x; }; template<typename T> class PseudoTest { public: PseudoTest() { m_pObj = new(m_buf) T; } ~PseudoTest() { m_pObj->~T(); } T *m_pObj; private: char m_buf[sizeof(T)]; }; int main(int argc, char *argv[]) { // First test the int case { PseudoTest<int> a; *a.m_pObj = 777; std::cout << *a.m_pObj << std::endl; } // Then if something prints out, that means that the // int pseudo-destructor has been called successfully. { PseudoTest<TestClass> b; b.m_pObj->print(); } return 0; }
One final word, note that I have used the placement new operator on a char buffer located on the stack and, according to Herb Sutter, this is a very bad thing because this generates non portable code. He explains why in his book Exceptionnal C++ (item 30: The "Fast Pimpl" Idiom) and then presents the right way to do it but since my test program compiles and runs fine, my evil code is will be fine for the demonstration purpose of this blog entry.
Question:
What is wrong in this code from the book 'The C++ Programming Language', section 3.7.2? and why does MSVC accept it and not GCC?
// Range checking vector template< class T > class Vec : public std::vector< T > { public: Vec () : std::vector< T > () { } Vec (int s) : std::vector< T > (s) { } // Range checking by using the at () method, // which throws out_of_range T& operator[] (int i) { return at (i); } const T& operator[] (int i) const { return at (i); } };
GCC reports this error:
since
at()
doesn't depend on any template parameters it should be available
Answer:
A compliant compiler will partially validate the template code that does not depend on the template parameters and complete the validation at the template instantiation point. It is that way because code depending on template parameter could have a totally different meaning if between the template declaration and the Point of instantiation (POI) there is a template specialization.
When you call a member function from a template base class, the way it is written is making the name nondependent. To fix the code, 2 options are available. You can either write:
1. is preferred as it will work as expected if the function called is virtual.
If VC++ does not complain, it is because it simply does not support the two phase lookup and compile templates only at instantiation point. GCC is a better compiler in that aspect because it complies with the C++ standard by implementing the Two-Phase lookup. You can easily fool VC++ with the following code:
template <class T> class Test { public: void Test() { foo(); } private: T m_a; } // Non dependent function declared after // template declaration int foo(); int main(int argc, char *argv[]) { Test<int> testObj; testObj.Test(); return 0; }
GCC will generate an error when encountering the template complaining that foo()
is not declared but VC++ will happily accept this code. Now that this is explained, note that except annoyance when porting code from VC++ to GCC or any other standard compliant compiler, the only consequence for MSVC of not being totally C++ standard compliant by not supporting the Two-Phase lookup is that if there are errors in a template, the compiler will delay their report at its instantiation instead of reporting them as soon as the template is encountered.
If you would like to explore further Dependant base classes, Point of Instantiation (POI) and Two-Phase lookup, I highly recommend to consult the book C++ Templates.
This book does a nice job for describing the pthread API. When I have read this book, my multithread programming experience was mainly with Win32 threads and reading this book was my first exposure to the condition synchronization objects. With the help of this book, it has been a breeze to learn how to use conditions. What is missing from this book written 10 years ago, which is also missing in all multithread books that I have read of that era, is coverage on issues with parallel processing. If all you have to do with threads is to launch a background job while keeping UI responsive or asynchronous I/O on a single core processor, you will be fine with this book.
However, if you try to crunch an array of data with multiple threads each processing their own chunk of the array, you could fall into cache line alignment problems even if your threads does not access the same memory locations. Those problems are platform dependant. I have written such a program that was working wonderfully well with a Sparc station and a PowerPC based station but once ported to a x86 architecture, the program was actually becoming slower than the single thread version. It is very hard to get it right. You have to be careful about the array alignment in memory and where the boundaries of the chunks of data that you assign to threads are. What will happen if 2 threads located on 2 different processors access to the same cache line is that one processor will have to flush that cache line back to the main memory and the other processor will have to fetch the values back from the main memory to its cache. The overhead of this is so huge that processing the array from a single thread could be faster.
I still have to find a book that addresses these problems. I expect it to come soon with dual and quad core processors becoming mainstream but this is not this book.
Not all of the 44 tips are exceptional. Some of them are pretty trivial such as "Read Stevens books" or "consult RFCs" but about 35 tips are very good. The author knows well this topic and explains very well the reasons behind these tips. I am sure that all these good tips can be found in the TCP/IP Illustrated books but if you do not have the time to read 3 volumes consisting of about 2000 pages, this less than 300 pages book will provide a nice synthesis of TCP/IP programming good practices.
I had to do some text processing and I wanted to learn sed & awk so I picked this book that is, to my knowledge, the only book completely dedicated to these tools. The chapter on 'advanced' sed programming is very scary because when using 'advanced' sed features, the syntax is cryptic. It is nice to know that these features are there but I want to stay away from them and perhaps use awk or perl for the tasks that would require those 'advanced' features. Still, when you stick with the 'basic' and 'intermediate' sed features, you can do cool things easily in shell scripts.
Overall, the book was not thrilling to read but it does a good job to teach you these text processing tools.
By having read the 3 books in the serie, I must say that this is my favorite because it has really answered a lot of small questions I had for a long time about several aspects of C++.
The only thing that I have disliked is that Mr. Sutter has contradicted himself with one of the advice that he was giving in the first book. The advice was to not write an assignment operator in terms of its copy constructor with the in place new operator and the explicit destructor and I did agree with the reasoning. Now in this book, it is written that is ok to use that idiom if and if and if and he goes for about a paragraph to describe the condition where it is ok to use the pattern. I can imagine that the author had to admit that there might be exceptional situation where it is ok to use that technique in a heated debate but my opinion is that out of context, he should not have mention that it might be ok to use that technique without devoting an entire item on that topic. It did just confuse me and I had to reread the item in the first book to convince me that there was effectively a contradiction between the 2 books and that it was not just my memory playing games with me.
Mr. Sutter's books biggest strength to my opinion is that they bring together a bunch of original advanced C++ topics that you cannot find anywhere else. This book has its share of very original content but I feel like the ratio original content vs topics that you can find in other books is lower in this book than with the other books of the serie. The most interesting section in this book in my opinion is the one on exception safety and the less original section is the one on generic programming and STL as you can find much of the information contained in this section in other books such as Effective STL from Scott Meyer or C++ Template from David Vandervoorde and Nicolai M. Josuttis.
In item 24 of the book Effective STL, Scott Meyers explains to be careful about using the overloaded subscript operator (std::map::operator[]
) when efficiency is important. The reason behind this advice being that when that operator is used to refer to an item that is not yet in the container, it will insert a new pair in the map by using the default constructor of the value part and then usually an assignation will be performed on the value reference returned by the operator. For non-trivial constructors and assignment operators, this can result to unnecessary overhead.
He then proceeds to present a function called efficientAddOrUpdate()
that calls std::map::lower_bound()
then performs some tests on the returned iterator to make sure that it is not equal to end()
iterator and if the key pointed by the iterator is equivalent to the key used with lower_bound()
. If the test is successful, then the value pointed by the iterator is updated or else std::map::insert()
is called with the std::map::lower_bound()
returned iterator as hint for the insertion point.
Few days ago, I had to recreate the efficientAddOrUpdate()
function without my copy of Efficient STL book available and I have being struggling for a good half an hour to an hour trying to recall the implementation details or find them back by doing searches on the Internet. I have finally come to the following realization by giving up searching the Internet and looking at the <map>
header file source code:
Scott Meyers efficientAddOrUpdate() function code is almost identical to the operator[] member source code function minus minor modifications
Here is the source code operator[]:
mapped_type& operator[](const key_type& _Keyval) { // find element matching _Keyval or // insert with default mapped iterator _Where = this->lower_bound(_Keyval); if (_Where == this->end() || this->comp(_Keyval, this->_Key(_Where._Mynode()))) _Where = this->insert(_Where, value_type(_Keyval, mapped_type())); return ((*_Where).second); }
and efficientAddOrUpdate()
code derived from it would be:
iterator efficientAddOrUpdate(map &m, const key_type& _Keyval,const val_type& _Val) { iterator _Where = m.lower_bound(_Keyval); if (_Where == m.end() || m.key_comp()(_Keyval, _Where->first))) { return m.insert(_Where,value_type(_Keyval, _Val)); } else { _Where->second = _Val; return _Where; } }
This book presents advices more or less in the same format than books from the Effective C++ serie. What is similar is that topics are divided in 47 small items of few pages each. The difference is that the author first ask questions to the readers or propose exercises and encourage the reader to put down the book and to take the time to think about the problem and then come back to read his answer. This format is more or less original as I have seen something similar in Tom Cargill's C++ Programming Style book.
I have read this book pretty fast which is a good sign of my interest in a book but in the same time this book did not leave me, at first, a strong impression that will make me remember this reading for a long time. It is hard for me to say exactly why but I think that it is because most items focus on very small details of C++. Some of these problems are very hard and probably is an indication that the book targeted audience is advanced C++ users which is not a bad thing by itself but I was not convinced that mastering these small details actually has a high impact on someone programming skills.
It took few months to let the wisdom contained in this book to sink in and I have found myself many times, in my day to day programming, confronted to problems where the material of this book helped to make wise design decisions. So now, I think that this book is very valuable for anyone that has mastered the C++ programming language and is ready to master tougher C++ issues.
Forward declaration is a technique that has at least 2 purposes:
For purpose #2, a TU (translation unit) that includes header file A but does not use the functions using the class defined in header file B and does not access that class, does not need to include header file B. That way if header file B ever change and forward declaration is used, this TU will not be recompiled. Taking systematically all the opportunities to reduce header file dependencies will not make a big difference on a project containing just a few TUs but it can save hours of compilation on big projects. Also, from experience, it is much easier to plan ahead and think about this aspect as the project grows than trying to remove the dependencies once they become a major problem for maintenance!
The reason why forward declarations work is because the compiler does not need to know the size of a class to generate code that handles pointer or reference to that type. A pointer or a reference always have the same size no matter the type.
Now that I have convinced you of the benefits of using forward declarations in header files, once you start using them, you might stumble on minor difficulties. How to forward declare a class inside a namespace? I have checked into the C++ bible 'The C++ Programming Language' from Bjarne Stroustrup and it remains quiet on the subject.
Fortunately, the answer is simple. Since namespace are open, all you have to do is:
namespace A { // Forward declaration class B; };
For nested classes, you can do it too but at the condition that it is done inside the outer class full declaration.
class B { // Forward declaration class C; };
is ok but
class B; class B::C;
is not. If this is something that you need, you either have to give up the forward declaration of B or move out class C out of B.
I had high expectations about the fruit of the association of 2 authors that I appreciate but the result did not meet these expectations. Basically this book provides 101 rules or guidelines that you can get for free by looking at the table of content. Each of these rules is then followed by a very short explanation (1 or 2 pages usually). In my opinion, most of them are common wisdom that you can get from other sources. This is it. That is all you will get from this book. For that reason, I recommend to skip this one except if a convenient and compact collection of common knowledge is something that you are looking for.
It is not perfect. One complain is that the first part is too easy and is aimed for total beginners and then there is the second part where a lot of material is presented too fast. I wished that the book spent less time with very basic (pun intended) VBA stuff but takes more time to make the transition to more advanced topics smoother.
Other than that, the book contains a lot of code that can easily be reused such as in my C++ tutorial that shows how to automate Outlook from a C++ program.
I have been disappointed by this book. I wanted it mostly to learn how to program Outlook. When I started reading it, I have realized that only a small portion of it was dedicated to Outlook.
Perhaps that I am harsh against the book value because I am not part of the intended readers but I guess that even readers interested to programming Exchange would not find much value of this book. I am saying so because the book is huge close to a thousand pages but it sounds like a cut and paste of the Exchange programmer user manual. When I purchase a book like this one, I expect it to be a complement to the product documentation, to give a better insight of how and why a given software works like it does. This book does not deliver up to these expectations.
The best Outlook programming book that I have found is: Microsoft Outlook Programming, Jumpstart for Administrators, Developers, and Power Users. Skip this one.
You have to know that its target audience is beginner C++ programmers. I am somehow experienced with C++ programming and by looking at the excellent reviews this book got, I had high expectations when I purchased it. I have been disappointed to only have found maybe 2 small advices that I did not know. Reading over 250 pages for a so small reward has been disappointing. If you consider yourself good in C++, my advice is that you should skip this one.
I have read this book because it was recommended by Scott Meyer in his book More Effective C++: 35 New Ways to Improve Your Programs and Designs and he was saying that this book was showing what C++ looked like on LSD. This book certainly contains interesting ideas and it demonstrate that the author has an exceptional creativity as a C++ user but Mr. Coplien best quality is not teaching in my opinion. To me, the text is opaque and hard to understand when the author is using terms such as "orthodox canonical form".
I did not like this book because I found it hard to read. Some books are hard to read but worth reading because they teach you something. This one is hard to read and I could not make any sense with the book content. You should definitly avoid this book except if you want to find a cure for insomnia.
First prior to reading this book, I was finding the title unattractive. I did not know what statecharts were and what Quantum programming was. By reading this book, I have learn that statecharts were special finite state machines that could be built by deriving them from more general FSM similar to how OO classes inheritance works.
Quantum is the name of the presented framework in the book. The title is misleading because I though that Quantum programming was some weird new programming technique that I was not aware and did not care to learn. I think that it is important to find catchy names to market software but one negative point of the book, is that the author spend way too much pages to describe similarities between quantum physics and his framework to justify the name 'Quantum' for his framework. Programmers are not all quantum physics enthusiasts!
Concerning the book content, the author presents the C++ classes implementing the statecharts framework and a set of classes to make threads driven by statecharts collaborate together by communicating with message queues. It is an interesting reading and there are many places where you can learn good programming tricks by seeing the author code. However, I am not sure that I would want to use the framework because it is complex. Let me clarify what I mean. It is not the framework that is complex but implementing statecharts is complex. I believe that the author made his code as simple as possible to implement statecharts. Personally, I still have to work on a problem where a simple FSM will not be enough.
The best feature of the book is its presentation of a base class to implement FSMs and compares it with traditional table based FSMs and a OO FSM like the one presented in the Design Pattern book and it is highly convincing that his FSM implementation is superior to the other 2 in size, performance and ease of maintenance. Another interesting topic is the author method to emulate C++ in C. You cannot beat the real thing with an emulation but when you have to go write C and you are used to do OO programming, this method might become handy.
I would say that for the FSM pattern and the C++ in C methodology alone, even if it represents a small proportion of pages in the book, it justifies the purchase of this book.
In my opinion, one of the most twisted part of the C++ standard (I am sure that there is more than just one twisted aspect) it is the friend function declaration in a class when you add templates to the mix. Even compiler implementers are having a hard time to get it right. I had the following code that used to compile fine in VC++6:
template< typename T > class X { friend ostream &operator<<( ostream &, const X<T> & ); }; template< typename T > ostream &operator( ostream &os, const X<T> &t ) { // Print out t return os; }
but now with VC++2003, I received this error message:
unresolved external symbol ostream &operator<<( ostream &, const X<T> & )
That code snippet is non conforming to the standard and in order to make the compiler happy, I had to write:
template< typename T > class X { /* * The '<>' is needed to say that the friend is a * function template. */ friend ostream &operator<< <>( ostream &, const X<T> & ); };
and for those who wonder, no I did not find the solution by myself. I had to look into my book C++ Templates. From section 8.4.1 (Friend Functions):
"An instance of a function template can be made a friend by making sure the name of the friend function is followed by angle brackets...If the name is not followed by angle brackets, there are two possibilities:
1. If the name isn't qualified (in other words, it doesn't contain a double colon), it never refers to a template instance...
2. If the name is qualified (it contains ::), the name refer to a previously declared function or function template. A matching function is preferred over a matching function template..."
So my example fits case #1 description so because of a bug into VC++6 (or maybe the standard was even not complete at the time of its release...), the compiler was erroneously accepting the friend statement as referring to a function template.
So this is the whole story. What I find sad is that the rule is not intuitive at all. There is no way I can reason it next time I am in the same situation. I will either remember the rule or I will have to check back in my C++ Template book. Herb Sutter has also written an item on that topic in his book C++ exceptional Style if you are interested in a different point of view on the topic but he pretty much comes to the conclusion that this is a tricky C++ standard aspect and that a lot of compilers have troubles accepting such statements.
The title is maybe misleading. It is not really a guide that will show you a procedure step by step 'how to do' to build secure systems as most engineering books do. It is rather a survey of the different security protocols used in various fields. Of course, you can learn from the success and errors described in the book and use this knowledge for developing a new system but you will have to connect the dots yourself.
The book is very dense in information and at first, its format was making it tedious for me to read. It did take around 3 chapters before I get accustomed to the format. Once, this aspect was out of the way, this book became amazingly interesting. It describes systems used in banking, by diplomats, military, for nuclear weapons, police, set-up box TV decoders smart cards and anti tampering devices in general, spies, biometric authentication, etc.. and focus on the security protocols used by these systems and then highlights the weaknesses of the systems and how people have figured out how to workaround these protocols.
The best quality of the book is that it will help you to better understand the mindset of a secure system designer and a system hacker.
The content of this book slightly overlap the content of the author previous book (Secrets and Lies: Digital Security in a Networked World) but presents the material with a different angle. An angle with the perspective of a security expert that witness security measures taken by governments in reaction of the 9/11 terrorism attack and wants people to understand the absurdity of some of these measures.
It is not technical at all and does not necessitate any particular background to understand and enjoy. The author explains clearly how to make a risk assessment of something that you want to make more secure and then evaluate the cost of the security measures. Only when you have that data, you can evaluate if the added security is worth it.
These explanations are backed up with concrete examples such as evaluating the risk to make purchase with a credit card over the internet. Other examples include the absurdity of securing a lunch in a company refrigerator because the potential loss if having a lunch stolen does not justify securing it. The author also explains that even with technologies that looks very accurate such as facial recognition with an error rate of, let’s say, 0.0001 % are totally ineffective when they have to control a huge number of persons like a stadium crowd because even with this accuracy, they would create an unmanageable amount of false positive alerts.
The author also elaborate about why you should question the motivation of a security provider when it is a third party and link this with how people fears can be exploited to introduce invasive, excessively expensive and inefficient security measures. I think that the goal of the author was to make people more critics about security questions and my opinion is that his goal has been successfully achieved.
This book is not very technical but it is very interesting to read and is very good to convey the basic principles of security. This book will teach you why security is more important than ever with the advent of computers and internetworking. It will present you potential attackers, their motivations and their resources. It shows how to add security to a system by doing some analysis of how the system could be attacked. After reading this book, you will have a better understanding of what it means to make a digital system secure.
Following Carlos Fernndez feedback, he pointed out that in the function CGradient::InsertSort() used by the tutorial sample program, the variable j that was declared inside the for statement was used outside of the for loop block. Strangely, my compiler has never complained about the problem but since it was trivial to fix, I just moved the j variable declaration outside the for loop statement.
You can read about that tutorial at:
That is a question a co-worker of mine asked. I did remember that I used to know what it does mean, but earlier today when I came back home, I have double checked in my COM reference book and I have found a subsection dedicated to the subject.
COM deals with multithreading by defining an apartment concept. 2 Apartment types exist: The single threaded apartment (STA) and the Multi-threaded apartment (MTA). One of the numerous COM class attributes is in which apartment type objects of that class are allowed to run. 3 values are possible for that attribute: STA, MTA or both.
When a thread wants to access a STA object, it will go through the same process than if the object was remote and will go through a proxy object, marshalling/unmarshalling and the thread residing in the remote STA apartment which must have a message loop, will receive the request. This whole process adds a lot of overhead and for that reason, COM allows to create a custom marshaller. Your COM object would have to implement the interface IMarshal. One example of a custom marshaller would be to serialize the whole object state to create an exact copy of it on the proxy side so once unmarshalled, all access to it would remain local.
Now, (I know the short explanation is starting to be long), in the case that a developer went through the process of making his COM class thread safe to support MTA, it would be a good idea to have a custom marshaller to just serialize a raw pointer to it for a safe direct access even when it reside in a STA apartment. This situation is so common that COM provides the custom marshaller that does it. It is the famous Free Threaded Marshaller and since COM does not allow inheritance to reuse code, the only way is to aggregate it to your COM object with the function CoCreateFreeThreadedMarshaler().
Aggregating a COM object just mean that when QueryInterface is called for getting an interface that the outer COM object does not support, it will forward it to the IUnknown::QueryInterface of the aggregated object.
This book is extremely complete. It briefly covers the history of cryptography. It describes the political implications of cryptography and finally it shows how cryptography can be used in applications and presents the different cryptographic algorithms.
The algorithm section starts with a number theory primer.Honestly, I have found it a little bit too thin to learn all the needed background to fully understand the algorithms but on the other side, you cannot expect a simple 600 pages book to provide that background in the latest mathematical research number theories. It has at least the merit that it did stimulate my curiosity about number theory when I have read the first edition of this book.
Another point that makes this book interesting is that at the end of each chapter presenting the various algorithms in a given category, you will get Bruce Schneier opinion on which algorithm is the best. Of course, this type of information usually become outdated real fast but it is interesting to follow his thought process and test his predictions as the book grow older.
So, if you are looking for your first cryptography book, it should be this one.
Beside Bruce Schneier books, this is the second software security book that I am reading. The first being Building Secure Software: How to Avoid Security Problems the Right Way and I have prefered this one because it provides more concrete examples. The book consists of over 20 chapters covering different security areas. As a software developer, some chapters appeared less relevent and less interesting to me and I guess that it is because these chapters are geared principally toward testers.
However, at least 2 chapters should be extremely interesting and valuable to developers like myself. It is the chapters that demonstrate with step by step tutorials how a hacker would do to exploit buffer overflow and format string problems. I was already familiar with buffer overflows and I had read a similar chapter about them in Building Secure Software: How to Avoid Security Problems the Right Way but the format string exploits were new to me.
As expected since the book is published by Microsoft Press, the book has a strong bias torward Microsoft products (ie.: .NET and ActiveX controls security) but the presented topics are general enough to make this book very valuable even for users of other OSes and/or development tools.
It is a good book but with the exception of the chapter on buffer overflows, my perception of the book is that it focus mainly on the theory of software security. As someone who has an engineer formation, I have a preference for books more pratical with more concrete examples. For this reason, I did prefer Hunting Security Bugs.
Consider the following program:
#include <stdio.h> void f(int i) { switch(i) { case 1: printf("case 1\n"); break; default: printf("default\n"); break; case 2: printf("case 2\n"); break; } } int main(int argc, char *argv[]) { f(2); return 0; }
What will be the output?
Intuitively because the cases might be evaluated in the order that they are declared to make 'fall through' possible from one case to the next one by omitting the break statement, the default case might be executed when i value is 2. I have checked my C++ reference book and my C reference book. The C++ one is silent one this issue but I have found this statement from 'The C programming language' book on page 58:
The case labeled default is executed if none of the other cases are satisfied....Cases and the default clause can occur in any order.
I still had doubt so I have compiled the sample program with Microsoft Visual C++.NET 2003 and with gcc version 3.4.4. Both compilers are compliant with what is specified in 'The C programming language' book and the case 2 is executed. Could it be possible that a compiler with a naive implementation create code that behaves as I intuitively reasoned? Maybe so for staying on the safe side and to make the code unambiguous for the maintainers, a good guideline is to always place the default clause at the end of the switch block.
Windows sockets are not like BSD sockets. The book explains very well the different specific modes into which winsock can be used: Blocking mode in a dedicated thread, asynchronous mode using Windows messages and Overlapped I/O that removes some memory copying when passing buffer to send/receive data from/to sockets. It also covers the Socket classes provided with MFC. In my opinion, this book covers very well the details specific to Windows version of the socket API and that will allow the readers to take advantage of this socket API version.
ATL is an interesting C++ framework to easily create COM classes. It uses extensively the C++ templates and is coupled with Visual C++ wizards to automate the writing of skeleton code of an ATL project. However there is not much documentation coming with VC++ on ATL and there are so much options in the wizards dialog windows that unless you know what you are doing, you will probably not do the right thing. This is where this book comes in.
First, one of the coauthor, George Shepherd, is also the coauthor of the book MFC Internals that I really liked. This book does a good job to guide you through the main ATL features. My only complain is that, like almost every other book on COM that I have read, it assumes that you know nothing about C++ and COM and takes the first 2 chapters to introduce you these topics and that represents almost 100 pages of prerequisite material that should have been found only in a introduction book IMO.
This book borrow the format that made the Effective C++ popular. It presents 50 tips on COM. Its targeted audience is developers that have been using COM for a while. Prior knowledge of COM is expected for reading this book. In general, it provides very good tips but the only exception is the section about MTS. Maybe the tips are good but I do not know as I have never worked with MTS. That section contains 8 tips of the 50 tips of the book.
Usually, when I read a book on a programming technology, I expect to see some source code somewhere. This book is surprising in that regard because it only contains plain english from the first page to the last. There was a hint on the cover page by indicating that managers are included in the targeted audience. This feature has some merits but is also a pain at some other places.
When presenting software to programmers, the most straight to the point way to present the material, it is with source code and I feel that at some occasions, a function definition would have replaced pages of explanations. On the other hand, it is easy to get lost in pages of source code filled with error condition handling code where a simple paragraph of plain english would have been enough to communicate the general idea behind a software module.
With these remarks in mind, this is why, as a programmer, I did not like the first few chapters describing COM basics and really appreciated the last chapters covering OLE compound documents, ActiveX and the usage of COM by MS Internet Explorer.
Yes it is outdated as it does not cover the latest features added to the standard. However it does describe in great details the core language and it is still the most detailed book about C++ to my knowledge after the C++ standard document text itself. Even the latest edition of 'The C++ programming language' book does not provide as much details about the language itself.
I have red this book for the first time 4 years ago. What I remember is that, at that time, I got few interesting informations here and there but overall the reading was more tedious than enjoyable. For some reasons, I have reread this book for a second time and perhaps because I could now relate my C++ programming experience with what the book explains, I have found it much more enjoyable to read this time. So my opinion is that to really get the maximum out of this book, you really need intimate knowledge and experience with the C++ programming language. I would not recommend this book for someone that has just started to use C++. Also, you have to know what the book is about. Do not expect to get practical knowledge to improve your C++ skills because you will not get much. The only exception is that this book made me curious about the "intersection" rule from Andrew Koenig about overloaded functions and made me look into the Annotated C++ reference manual to know more about it. This book is more about the C++ history and how and why certain design decisions have been taken about the language. If this is what you are expecting, you will like the book.
I have learned a lot with this book. I would not qualify the book an introduction book because unless you have some background knowledge and practice, you are going to find the last chapters hard to digest. What the book does is to covers the essential principles of COM with great details. This will make the first reading very interesting and it will make you come back from time to time to seek back specific detail.
I want to set the expectations straight. This is not the best Winsock programming book. This book address higher level issues with network programming and it does a very good job at it. It is going to presents the different options for writing a server such as concurrent vs iterative or single thread vs multithread and explains carefully the tradeoff of each option. In my opinion that is the strength and the originality of the book. Another favorite part of the book is the presentation of the complete implementation of a telnet client where the author leads you through all the design and implementation process by explaining you the reasoning behind each decision.
What I did not like about the book is that like the volume 1, too many topics are covered so in many chapters the author barely touch the topic without going in depth into it and I am questioning the value of these chapters as reference.
This is the Windows version but there is also a Linux/Posix Sockets and a BSD sockets versions.
This book goes in depth in how TCP/IP works by showing an actual working TCP/IP stack ANSI C code source. I am a believer that in order to fully understand and effectively use a piece of software, the best way to achieve this goal is to actually study at least once its source code. You will certainly get many insights in how TCP/IP works by reading this book. Unfortunately, for most readers, this will remain a theoretical exercise. I got the opportunity to work with the source code of an embedded TCP/IP stack when I was working at Nortel Networks and actually found a bug with the help of this book. That was at that moment that I truly realized the value of this volume.
This book describe the TCP/IP family protocols. Of course, there is so much to say that in the limited space that a book can offer that I would say that the book presents only a quick overview of the protocols. Fortunately, at the end of each chapter, there are pointers on the relevant RFCs for the discussed topic in that chapter. My next statement is an impression and not a proven fact but by having read the first edition a long time ago, I have the impression that some details have been removed in this edition in favor of a better coverage of more new protocols. That being said, the information contained in the book is extremely accurate and the book is very useful when analyzing the output of a packet sniffer such as WireShark (previously known as Ethereal).
This book is probably the best COM introduction book for C++ programmers. It walks you through the basics such as the IUnknown and the IDispatch interfaces, the different types of COM servers and the threading models. Everything is explained in clear writing style.
I am a big fan of the ACE framework. ACE is an open source C++ framework to develop networked applications and offers a free CORBA implementation. Once you have mastered the TCP/IP protocols and are ready to develop networked applications, this framework makes the development a breeze. However, due to its intimidating size you are much better to learn how to use this framework through these books.
I have also read Programming ADO from David Sceppa and I prefer this one because it contains a lot examples with source code. My only complain is that there is only a small C++ program and the rest are all in Visual Basic. However, this is not a big issue as it is very easy to port the samples in C++.
This book is fine but I have prefered the book ADO: ActiveX Data Objects by Jason T. Roff for its numerous source code samples.
I like this book because it is a good compromise between lex & yacc man pages and the theory found in books such as the Dragon book. You will get valuable information about the how and why of the tools that will help you to produce a quality grammar without being overwhelmed by details.
This is the classical reference book for compiler design. This is not an easy text because of its heavy use of mathematical notation and the algorithms are presented only in pseudo code but you will not find a more complete collection of compiler related algorithms than in this book.
There is a new edition that I have not had the chance to review.
This is the book I used in my AI class. I have found it very well written and interesting to read and go through the very first neural networks models such as the Hebb net, the perceptron and the Adaline. Then the book continues by presenting simple neural network applications like pattern association.
I remember that our professor did ask the class to do one of the proposed projects in the pattern association chapter which consisted of implementing a small OCR with a neural network and this exercise did really help to better assimilate the principles. Finally, the following chapters present other types of neural networks such as those based on competition and the very important backpropagation neural network.
The only thing that you can complain about is its high price tag. For anyone interested in the AI field, it is recommended.
The book title suggested to me that the book would follow the Effective C++ series format where advices are given in small items. This is not the case. This book has a more conservative format where topics are presented in chapters. This is not a problem per se but I just wanted to say it to potential readers that could have the same impression that I had by seeing the title. That being said, the topics covered are the usual areas where you can usually gain some performance such as temporaries, memory allocation and inlines. I cannot say that I have learned a lot of things because writing performant C++ code has been a topic of interest to me for a very long time.
The chapter about inlines is mixed bag of very good information and useless information. What I did appreciate less is that several pages are dedicated for describing what could be possible to do with inlines if very smart compilers were available. It was interesting to read but nothing applicable immediatly. Maybe this section is a wish list intended to be read by compiler implementers. However at the same time, it is the chapter that gave me the most new tricks that I did not already knew. This is the book that presents how to efficiently use inlines in the best way that I have seen in books.
Finally, if I abstract the fact that I did not learn a lot of new things, I must say that it is very well written. It is interesting to read. The authors give reference to actual cases from their work experience and this book would probably be very beneficial to read for someone that has never yet spent a lot of time doing code optimization.
I have read tons of C++ programming books. A lot of them lack of originality. This is where Tom Cargill book shines. The author of this book first presents a small C++ program listing for each chapter and then ask the readers to take few minutes to try to identify the errors or the aspects that could be improved. It is really instructive to find out all the things you have not identified yourself and this is what makes this format so interesting. Some people says that this book is for novice programmers but I disagree. To my opinion, almost all experienced programmers will miss at least half of the problems present in the sample programs.
10 years ago this book revolutionize the way programmers see object oriented programming. At that time, it was essential to read it. In fact, I remember that employers were testing candidate knowledge on design patterns at job interviews. Today, I consider this book as a classic that I would recommand to read for everyone that has just learned object oriented programming but it is less essential than it used to be as design patterns knowledge has spread in the litterature and you could even learn about them just by working on existing code. That being said, this book is still very valuable even for people that already know about patterns. I am on my second reading after many years of using the design patterns and I am picking up new insights that has escaped my attention at the first reading.
Following in the tradition of his prior books, Meyers delivers another gem with Effective STL. This one is a must have for your software development bookshelf. The only detail that annoys me a little bit is the amount of cross references between the items. The author first 2 books were a little bit like that but it seems to me that this one is too much. I would have preferred to have items more self contained. If you want to read a particular item, this one will refer to 2 other items that will refer to some more items and so on to the point where if you would like to close the open loop, you would need to consult almost all the items.
Except for this small annoyance, this book is very good. You should read it or have it.
It is a tutorial and a complete reference at the same time. I already knew very well STL when I have read this book but reading this book has been very enjoyable because I really appreciated its format. The tutorial and reference part are not clearly separated in 2. I hate books where you never read the reference part because it is as fun to read than reading a phone book.
Of course, the first part is strictly tutorial where it introduce STL, its basic principles and a quick overview of all the services provided by the library to the reader. Then lengthy chapters follow to cover containers and algorithms. This is where the book shines. It covers one by one each container and each algorithm and to support their description, a small sample program follows.
Before this book, there were some algorithms that I could not figure out exactly what was their purpose or how to use them correctly just from their description in the STL man pages. By reading the samples source code of this book, I had many 'AhAh' moments where finally I could understand some algorithms less frequently used. For all there reasons, I am very happy with my decision to get hold of this book.
Like every sequel, in my opinion, this book is less good than the original as if the topics covered in this book are the ones that did not make it into the original book. However that being said, this book is still very good and is just more of the same good stuff that made the original book a bestseller. If you liked Effective C++, there is not risk at all that you will not like this one and will get new knowledge out of it.
This book is a classic. The 55 advises can certainly be found in other books but the strength of this book is in how the author walks you through intelligent explanations on why it is wise to follow the advise. Beside, the writing style of the author makes the reading of this book as enjoyable as reading a good novel.
This is highly recommended as you will learn while having fun.
Before this book, most C++ textbook were at most devoting one chapter on templates which clearly is not enough to cover a topic as complex as the C++ templates. The C++ Templates book is filling this void nicely and one of the coauthor of the book is the author of my favorite STL book 'The C++ Standard Library'. The book has 4 parts: The basics, templates in depth, templates and design and finally advanced applications. Personally, I found the 2 last parts good but less interesting because I think that other books such as Modern C++ Design do a better job to cover templates applications.
Where this book really shines is the first part that covers the C++ templates syntax very well. With a capricious syntax like the templates one, a good reference is essential. One example that come to my mind is when I was trying to declare a friend template function from a class template. That sounds like a simple thing to do but it is not. The syntax rules for this declaration are, to my opinion, far to be intuitive and hard to find in regular textbooks. With the help of this book I have finally been able to fix my friend template function declaration and make my compiler happy.
This book is both a text book for learning C++ and a reference book to consult whenever tricky C++ interogations arise. I would qualify the writting style as academic and very dense in details. It has the merit to be very accurate and to cover almost every aspects of the programming language but in the same time, it is the very same reason why not a lot of people that I know went through the book from one cover to the other. This book is for serious reading and is not a fun easy reading before going to sleep. The writting style might intimidate people that have never had experience for C++. For that reason, I would recommand newbies to look elsewhere for a first book to be introduced to C++ Accelerated C++: Practical Programming by Example from Andrew Koenig would be a good suggestion. However, for any intermediate to expert programmers, this book is a must. To me, reading this book after few years of C++ usage helped me to fully integrate all the details of the concepts that I was already using on a daily basis and this had the effect of bringing my C++ understanding to a new level.
I read a lot of programming books (maybe too much sometimes... :-) and I think that I am getting very hard to impress but I must confess that this book is very special. It is one of the rare book that did really open my eyes on new possibilities for programming. What the author is doing with templates are things that I have never imagined possible.
The basic concepts presented in this book are policy based class design mixed with some template metaprogramming tricks. The rest of the book consist of revisiting classic design patterns such as smart pointers, singletons and factories by implementing them by using policies and template metaprogramming. The result is, to my opinion, impressive. Implementing these classes may at some point add some complexity but customizing the end result classes is incredibly easy, flexible and requires minimal changes.
Some people did not like the book by arguing that they were not sure if they would be using the patterns presented in the book. I agree with their position and I am not sure that I would find a usage for all the patterns presented in the book or if I would just not want them in my code by fear of the added complexity but in my opinion this is not a good criteria to judge the book. It is not important to know if you are going to use the presented patterns or not. What reading this book will do for sure is to widening the horizon of what you know possible with C++ templates and bring new ideas on how some programming problems can be solved. How many C++ books can do that? For myself, they can be counted with one hand. If you retain the general concepts, it is not important to know if you will use the details.
If you want to know more about strange attractors and the Feigenbaum diagram, this is the book for you.
These are the books I used to learn how to create the fractal images I show in this website. I highly recommend these books as the author writing style is superb. You can read these books almost as if they were novels. In fact, if you read these books, you might even start to be a Clifford A. Pickover fan as I did! This author has written an amazing number books. One can wonder how he finds so much inspiration. You should check the list of books written by Clifford A. Pickover!
This book is a monster brick of over 1300 pages with 70 chapters! Do not be misled by the book title because the 22 first chapters, which represents about the third of the 1300 pages, discuss assembly optimization. This book is getting a little bit old and a little bit outdated. For instance, this author covers optimization techniques for processors ranging from the 8088 to the Pentium and the Inner loops book covers the 486 to the Pentium Pro.
The second part covers low level graphics programming in assembly. The type of graphics programming that people were doing before Windows and DirectX.
Because assembly programming is not very popular anymore, for most people, it is not a good book to get but if assembly optimization is your thing, then you should consider this one as even if there are more recent books on x86 assembly programming, this one is the best that I have seen to lay out the basic concepts such as branch prediction, register contention, how to shuffle assembly instructions to optimize the processor pipelines usage and how to optimize the flag register usage. Armed with this knowledge in the back of your head, even when you write C or C++, you will be able to subtly change the way you formulate if/else blocks and for/while loops that will enhance your program performance without affecting the code readability.
It has historical value more than anything else...
This book is divided in 2. The first part describes the theory of assembler optimization for processors from the 486 to the Pentium Pro. 10 years ago, this information was useful but now it is pretty much deprecated as I highly doubt that Pentium optimization techniques do anything good on Athlons or Pentium IV processors. The only chapter that still contains applicable information today is the one providing general advices on optimization such as loop unrolling.
Then the second part named 'Practice' provides concrete examples of assembly optimizations for various problems such as sorting, list and tree traversals. I do not like this section neither because I feel that the presented assembly procedures are thrown at you in the face without showing you the process that the author used to derive them from the original C code. Michael Abrash's Graphics Programming Black Book does a much better job in that area by presenting you 5 versions or more of the same procedure starting from the C version that gets optimized further at each iteration. Also, someone might expect to be able to get the source from the CD-ROM coming with the book and start directly using it. Alas, it is not possible because what the presented code is sorting or searching in binary trees are integers that are directly manipulated in the registers (that is part of the presented optimizations) which has not much reuse value in a world of STL containers holding usually much more complex objects or structures than plain integers. The only value that these examples might have is that they might give you some ideas on where assembly optimization might be applied.
A much better book to learn the process of optimizing in assembly is Michael Abrash's Graphics Programming Black Book because it walks you through the optimization process step by step with more than 5 versions of the same procedure that is getting more optimized at each iteration. You will learn how to do it yourself with this book even if it suffers of the same weakness than this book. That is: it presents optimization techniques from the 8088 (that is very very old up!!!) to the Pentium Pro. Another benefit from Abrash book is that, in my opinion, there is a greater chance that you might find its code reusable.
Finally, a very good optimization book that covers optimization techniques for recent processors such as the Athlon and the Pentium IV is: Code Optimization: Effective Memory Usage.
This book has been a revelation to me. Prior to read this book, all I knew was that memory access was expensive. This book will teach you how to organize your data in memory and how to access it to improve your program performance and most of the time without having to use assembly programming. It covers x86 memory organization and the interface between the processor and the memory and there is a whole chapter covering x86 processor cache memory. To me, the most shocking information contained in this book is a C implementation of memcpy() that outbeats VC++ implementation by 25%-30%!!!
This book is not for novices but if you are ready to change your perception forever of the x86 programming, this book is highly recommended!
This is a very old book dating from Windows 3.1 era. It walks you through the methodology one could take to encapsulate the Windows API in a C++ framework. Most of the information contained in the book is still accurate today except for one chapter related to memory management.
This book covers in details the GDI API and the DirectDraw API. Even if it was written for Windows 2000, it is safe to assume that these APIs have not changed much in Windows XP. The source code samples contain mistakes but it remains an excellent reference. I recommend this out of print book because you can probably get it for a very cheap price.
It does a very good job at describing the Win32 API for multithreading but the applications of multithreading assumed is strictly I/O related (Networking, printing, writing/reading files). The set of techniques for parallel processing on the same data is completely absent such as data organization in memory to optimize its parallel access. This is probably due to the age of the book as when it has been written, single core processor system was the norm. Parallel processing will become very important with the growing popularity of the multi core systems. Despite this weakness, this book is still my best recommendation for learning multithreaded programming on Windows since, to my knowledge, there is not yet any book tackling the subject of parallel processing on a Windows/x86 platform.
The difference between this book and Programming Windows with MFC is that while the latter provides a complete reference on how to use MFC, it does not cover much what is going inside MFC. You might ask why should care about how MFC works? If you remember the first time you used MFC, you might remember your astonishment about how quick you could have a working decent application in five minutes just by using the MFC wizard but after that joyful moment, you spent frustrating weeks to figure out how to do add this special feature to your program. Lets face it, the documentation coming with MFC does not tell everything you have to know to fully unleash the power of MFC. The only way to truly understand MFC is to dig in the code (For Star Wars fans, Obi-Wan would say "Use the source, Luke") and this is precisely why Microsoft is providing the MFC source code. MFC source code is huge and might be intimidating at first. This is why having a book to help you in the first steps of your exploration is an excellent idea. Consider having this book as a companion for Programming Windows for MFC. However, this book is not for novices. Only buy it, if you consider yourself good with programming MFC.
If you buy it, very interesting discoveries await you! You can see by yourself by looking my MFC tutorials on my website what the knowledge contained in this book has allowed me to do with MFC.
This book is considered as the windows programming bible by many. Sure, you can build applications without all this knowledge with frameworks such as MFC but if you are looking to build a Windows program that do exactly what you want, there is no workaround a deep Win32 API knowledge. This book is a must for all Windows programmers bookshelf.
Something you need to know before purchasing this book is that it is very unlikely that the author will update this gem one more time as Microsoft is slowly phasing out the Win32 API in favor of the .NET framework and this will be even more real when Vista comes out. However, since there is a huge codebase of existing Win32 programs, the Win32 API will certainly stay around for a long long time. This book is simply the best for learning Win32 programming. I still refer to it very frequently. If you are looking for a reference book on Win32 API, this is the one you were looking for.
This book is more accessible than the Dragon book but is less complete. This book presents complete source code for parser generators tools and a C compiler. Even if this book is getting a little bit old and it targets a DOS platform, it should not stop you from acquiring this goldmine of very useful information for anyone interested in compilers for a very reasonable price.
This is the most detailed book that I know about GDI programming. If you have the courage to go through this brick (it is about the same size than Programming Windows and Programming Windows With MFC), your understanding of GDI will be greatly improved.
I have loved this book. It is much more easier to read than the more detailed book Windows Internals but still give you a good overall understanding on how Windows works. After having read this book, the cryptic access violation error messages suddenly made more sense. The most enlightning chapters of the book are the ones discussing how the OS manages the process memory space and how a process is launched. Do not get fooled thinking that because the book is on NT that its information is outdated. Not much has changed since and its content is still accuratly accurate.
To be honest, I have never had the chance to get my hand on this book because of his high price. It his on my wish list and has good reviews.
This book is to MFC what Programming for Windows is for the Win32 API. I would call it the MFC bible. There is a lot of MFC books out there but Programming Windows with MFC is one of the best. If you are serious about MFC, you should consider adding this one to your references collection.
Every examples of member template that I have seen be it in the C++ Template book or in Mr. Stroustrup book consist of templatized copy constructors or assignment operators where the template argument can be deduced from the member function parameter. I wanted to write a member template with no function argument and I could not find in both mentionned books how such function could be called. Here is an example:
class A { public : /* How do you call doX() ? */ template <int ID> doX() {} };
I have found out by experimenting that it is the exact same syntax than for function template:
A a;
a.doX<1>();
I have written to the authors of the C++ Template book to point out this omission in their book and here is what David Vandervoorde has nicely answered:
Hello,
Thanks for the feedback -- I think I agree.
Do not forget section 9.3.3 ("Dependent Names of Templates") in C++ Template, which may apply in cases like this. E.g., using your example as a basis:
template<typename T> void f(T x) { x.template doX<1>(); }Without that extra "template" keyword, the code would be invalid.
Cheers,
Daveed
Today is my last day at Quazal, the online gaming middleware provider. I have been working there for the last year and a half and have been involved in many projects such as the Relic Company of heroes lobby server, Supreme Commander, Atari Test Drive unlimited M.O.O.R. (Massively Open Online Racing) and Ubisoft Splinter Cell Conviction.
I am also the person who designed and implemented the generalized routing system that enhances peer-to-peer connectivity in Net-Z that Quazal should announce in the next few days. There are many purposes for this new feature. First, it allows developers to create online games in a client/server topology. Secondly, routing can be used in a peer-to-peer setup to enable the connectivity between players in the event that they would be behind NAT routers that make the connection impossible (any combination of strict and moderate NAT routers). As an extra bonus, Net-Z bandwidth usage has been optimized during the implementation of the new feature.
In two weeks, I will start to work at Stream the world on their audio/video streaming server. Its going to be very a very cool challenge!
A NAT router is a device that allow many computers to share the same IP address. You can learn more about NAT itself from Internetworking with TCP/IP, Vol 1 (5th Edition). One drawback of using NAT is that to communicate with someone outside the private network, you must initiate the communication from the private network. This is all fine for contacting a web server but this is making peer to peer applications such as file sharing or gaming harder. There are some techniques to perform NAT traversal but what makes the matter worse is that NAT routers have a different NAT behavior from a model to the other and as if it was not bad enough, these behaviors are totally undocumented. Things are about to change as the RFC 4787 describes a set of behaviors that a router should have to be gaming friendly. So my advice as a person who has worked at Quazal, a big well known multiplayer online middleware company, if you want the best NAT router for online gaming for your video game console (Xbox, Xbox360, Nintendo Wii, Playstation 2, Playstation 3 or PSP), you should look for a router that is RFC 4787 compliant. They might be hard to find now as the RFC has been released just few months ago but if I personnally was looking to purchase a new router, that is what I would be looking for.
The basic principle to perform NAT traversal is that you need a server on the public network that will be used as a traversal probe relay. Lets say that client A and client B that are located behind 2 distinct NAT routers. They first have to contact the server. The server must keep the address from which it receive data from the clients. These addresses are the public address of the clients behind the NAT router as seen from the server. When client A wants to establish a connection with client B, it will first request the client B public address from the server and start sending probes to B public address. At the same time, client A will send a request to B by using the server as a relay to start sending probes to itself. What will happen is since both clients try to establish a connection with each other at the same time, there should be a midair collision where a hole has been created for the other on each of their respective router. This technique is called hole punching and there is an RFC describing a protocol that implement this principle. The protocol name is STUN (Simple Traversal of UDP for NAT).
NAT traversal for TCP is much harder because TCP handshaking for establishing a connection is asymmetric. To workaround that problem, you have to trick the TCP protocol and the router that might monitor the TCP handshake. There is not yet an official protocol but some proposals exist. One of them is STUNT (STUN for TCP) but the name is funny because it has also a second meaning. The way STUNT works is that both side will initiate a connection by sending a SYN packet with a short TTL (Time To Live). The TTL value must be carefully choosen so the packet goes out of the private network but does not reach the destination. Then the stack itself or a packet sniffer must read the sequence number contained in the SYN message and send the read value to the STUNT server. The server will then impersonate the other endpoint and spoof the SYN/ACK reply. Then the last step of the connection which is to send the final ACK can be sent as usual and if everything has worked fine, the TCP connection will be established normally. I will stop the NAT traversal explanation here as there are a lot of good resources on the net. Here are the most interesting:
Update (12/05/2010): I have written a review of Linksys and a Netgear gaming router if it can help you to choose the right router for your needs.
While setting up my Microsoft Outlook 2003 client to use my new hosting company, BlueHost, SMTP server, I was always getting a connection timeout every time I was clicking on the 'Test account settings'.
After investigating further the problem, I have found out that a TCP connection was established with the server but it was taking an unusual long time (around 35 seconds) before receiving the server '220' "Greeting" reply.
My first reflex has been to look into my book Internetworking with TCP/IP, Vol 1 (5th Edition) in the chapter on Electronic Mail and I have found:
If the server is overloaded, it may delay sending the 220 READY FOR MAIL message temporarily.
Then I went to check what the RFC 2821 text was saying about that topic and I have found in section 4.5.3.2 Timeouts:
Based on extensive experience with busy mail-relay hosts, the minimum
per-command timeout values SHOULD be as follows:Initial 220 Message: 5 minutes
An SMTP client process needs to distinguish between a failed TCP
connection and a delay in receiving the initial 220 greeting
message. Many SMTP servers accept a TCP connection but delay
delivery of the 220 message until their system load permits more
mail to be processed.
Here you go. The RFC recommends to set the timeout value to 5 minutes and the Microsoft Outlook 2003 default value found in the 'Advanced' tab of the 'More settings' dialog is one minute. I have tried to set it to 5 minutes and then I have retried to test my new settings again. The test was still failing. I have found out the reason. The server timeout seems to be hardcoded to 30 seconds or less when you click on the 'Test Account Settings...' button.
So, to make a long story short: If you have to connect to an overloaded SMTP server with Microsoft Outlook 2003 client (I do not know if there are other versions affected with this bug), the real test for your new account settings is not the test button but to actually try send manually a test e-mail.
Hurray,
I have moved away from my free personal web page to a real hosting solution. It took a lot of time and energy and that distracted me from writting about programming but I am quite happy of the end result. It was well worth setting it up for the last week. Also as a bonus, I got a fully functionnal blog. I still have to tweak a small visual glitch on each side of the blog frame but after that, I will return to the main program that is writting about C++ programming. As a small teaser, the next covered topic is a small omission in the book C++ Templates from David Vandevoorde and Nicolai M. Josuttis that I reported to the authors which resulted to a nice exchange with Mr. Vandevoorde. Needless to say that this topic does not have a lot of coverage.
That being said, I must say publicly that I am totally impress with my new web hosting provider. The competition is probably ferocious but I could not beleive that I could get that much for only 6.95$ per month. This whole blog engine was part of the deal and on top of that, they have a very good and quick technical support be it ether on the phone or by e-mail. Anyway, I will stop the suspense in case that you would be curious now, I am talking about Bluehost.com
I want you to find in this blog informations about C++ programming that I had a hard time to find in the first place on the web.
<< | Current | >> | |
Jan | Feb | Mar | Apr |
May | Jun | Jul | Aug |
Sep | Oct | Nov | Dec |