Home > C/C++ > The Mysteries of C++

The Mysteries of C++

I like C++, but sometimes it appears to work with the aid of magic which I don’t fully understand. Last time (was it really 3 weeks ago?) I mentioned a problem I had with compiling the software I have been offering to subscribers to this blog with the GNU compiler. Or, to put it more honestly, I created a problem which g++ legitimately complained about, but which the other two compilers I tried (VC++ and IAR)  allowed me to get away with. I am simplifying somewhat but basically I coded something like this:

// In a header file...

template<class T>
class A
{
private:
    static unsigned int const k;
    static unsigned int array[];
};

template<class T>
unsigned int const A<T>::k = sizeof(T);

template<class T>
unsigned int A<T>::array[X];
// Where X represents a compile-time expression involving k.

// =========================================================

// In a cpp file somewhere...

class B: public A<B>
{
    // ...
};

The GNU compiler complained that I was referring to the size of an incomplete type, and pointed me to the line where I defined k. Guilty as charged. How can the compiler know the size of a specific T-class before it encounters one? What astounded me though, after I realised what I had done, was that it was not the template definition of k that caused the problem. I proved that by removing the array, at which point all the compilers did their work without complaint and set the correct value for k when instantiating A<B> as a necessary part of  compiling B. On further reflection, it would be tricky, perhaps, if compilers couldn’t handle this, but I haven’t had the time or the inclination to assume the mindset of a compiler writer and think this through properly. I just stand in awe of such people!

The problem arose in the attempted use of k in calculating the array dimension, X. For g++, this was a step too far. Clearly, the other two compilers chose to defer definition of the array until after compilation of B (including the instantiation of A<B>) was complete, whereas g++ did not.

Of course, after I discovered the nature of the problem, I Googled for it. As is usually the case, others had been there before me. But my new problem then was what to do about the code I had written and published on this blog. Well, I found an easy way  to fix it and, as a bonus, the new code is neater and more elegant than the old.

Unfortunately, lack of time and estrangement from my main computer (it’s in the UK and I’m in Switzerland) prevent me from making the new code fit for release before Easter, when I will be reunited with said computer. I will publish it then.

Advertisements
Categories: C/C++
  1. Gsidhu
    Friday, May 20, 2011 at 00:25

    Hi Peter,
    I am interested to know what the work around was, as i noticed something similar in the code written by my one of colleague.
    Thanks in advance

  2. Peter Bushell
    Friday, May 20, 2011 at 16:13

    @Gsidhu
    I was trying to allocate a static array to provide the pool space. The array-size calculation involved the size of the user’s object (derived from Pooled). Unfortunately, the viability of such a calculation depends upon the order in which the compiler processes things in constructing the various objects. Some compilers handle it; some don’t. None is required, by the C++ standard, to handle such esoteric stuff!

    I got around the problem by allocating the initial pool space dynamically instead of declaring an array. (Static allocation, as originally attempted, would have been better, but I couldn’t figure out a reliable way to automate it.) The pool memory can be taken from the standard heap (if you must); the actual pool is never given back, so there is no fragmentation issue. The preferred method, though, is to use my super-simple allocate-only code for obtaining pools. This is a configuration option and it works completely transparently – the user doesn’t have to manage the initial allocation of pool space, except to ensure that sufficient total space is made available.

    If you haven’t already downloaded the code, I suggest that you do so and have a look through it. I expect to be updating it again soon, and will post another message when I have done so.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: