May 2007 Archives
2007-05-14
Reading C type declarations
If you are interested, in what exactly char
*(*(**foo[][8])())[]; declares go on an read this.
Yes, this is no C++ but a C topic. But as ISO C++ is (almost) a superset of C89 this nevertheless matters. Furhtermore it's fun. And a good example on how a language should not be defined.
2007-05-14
Weltanschauungen
Die gefährlichste Weltanschauung ist die Weltanschauung derjenigen, die die Welt nicht angeschaut haben.Alexander von Humboldt
2007-05-12
Illuminate
A friend of mine just told me that he too hit the vector trap of my previous post. Instead of reading the STL code he wrote a class with debug output to track down what happens to the objects inside of the several containers.
Yeah! The illumination class. This is what everybody hacks at least once in his C++ live. And here goes mine:
class Illuminate {
public:
Illuminate() : _id(id++)
{
cout << "default constructor " << _id << endl;
}
Illuminate(const Illuminate& rhs)
: _id(id++)
{
cout << "copy constructor " << _id << " <- " << rhs._id << endl;
}
Illuminate& operator=(const Illuminate& rhs)
{
cout << "operator=" << _id << " <- " << rhs._id << endl;
return *this;
}
~Illuminate()
{
cout << "destructor " << _id << endl;
}
private:
static int id;
const int _id;
};
int Illuminate::id = 0;
Use it for example like this:
int main()
{
vector<Illuminate> foo(3);
cout << "mark" << endl;
}
The program output then shows clearly what I tried to explain in my
previous post:
default constructor 0 copy consstructor 1 <- 0 copy consstructor 2 <- 0 copy consstructor 3 <- 0 destructor 0 mark destructor 1 destructor 2 destructor 3
2007-05-12
STL Fuckup
Today I have two things to say:
First beware of SGI's Standard Template Library Programmer's Guide. Although it is the STL docu out there it is not standard compliant!
For example it
claims there is a vector(size_type n) and a
vector(size_type n, const T& t) constructor for
the vector class. This is not true. Section 23.2.4 of the ISO-C++
standard defines explicit vector(size_type n, const T&
value = T(), const Allocator& = Allocator());.
You could argue that they just split the two cases into to different constructors. But apart from the missing default value for the second argument and the completely missing third argument this is not true. SGI explains:
vector(size_type n): Creates a vector with n elements.vector(size_type n, const T& t): Creates a vector with n copies of t.
And this leads to today's second point: there is no constructor to let the vector be filled with n objects each constructed by the default constructor. Instead the objects in the vector are always copies of the given one - which is discarded afterwards, by the way. This is a problem as soon as it matters, whether the objects are copied or not.
For instance imagine some struct Foo with a smart pointer of
some type Bar being a member. The Foo constructor creates a new Bar
object with operator new and passes the pointer to the
smart pointer's constructor. What you want if you arrange such Foo
objects within a vector normaly are n different Foo objects. But
what you get are n Foo objects whose smart pointers all encapsulate
the same Bar object. This is because the Foo constructor runs only
once. The rest is done by the copy constructor.
I see no efficient way to get the vectory filled with n independent Foo objects. The best way I can see is like this:
vector<Foo> v;
v.reserve(n);
for (unsigend i=0; i<n; i++) {
v.push_back(Foo());
}
Anyone a better idea? If yes send me an email. I'm eager to knonw
whether I miss something.2007-05-09
Memory Layout for Multiple and Virtual Inheritance
2007-05-09
Barriers
In addition to my post about why it is a problem that the compiler does not know anything about threads I recommend this article about memory barriers and multi core machines.
And please help him find pi :-)