Skip to main content.
August 16th, 2005

Slowly going back to C.. again !

After this long new trial with C++, I feel like I’m sliding into back into C, although I’m still searching for the right balance.
It’s not that I don’t appreciate OOP, it’s rather that C++ seems to be truly messed. There is a wealth of tricks & tips, templatized this and that.
I must admit that the language is truly powerful. It allows one to do things in so many ways… but at a practical level, it has some very dull issues. I understand that C++ had to make compromises to keep the performance up. However, it doesn’t really give much hope to those that wish to do clean OOP.
Again, the single biggest issue is the fact that one must declare all members of a class in the header, including the private ones.
I think I’m right to assume that it’s a good coding practice to split larger function/methods into smaller ones. The so called “helper functions”. With C++, every time one writes an helper, he/she has to go back into the include file and add the declaration for that function.. ..for large projects, we are talking about a lot of them. So much for C++ being sold as the language for large projects !
This is a real pain for someone that has worked with Java. Java has some implicit performance issues that I don’t like, nor I like the fact that it doesn’t support callbacks. However, it’s a language truly committed to OO, and it’s nicer towards the programmer: no need to copy and paste every single function one writes !
Keeping at the practical level, the fact that one has to expose the internals of a class along with its public declaration, it means that the code that simply wants to use the class (the user-code), may have to include a lot of useless additional header files.
For example, let’s assume that I do a 3D library. Internally it uses Direct3D, some private functions will use pointers to D3D texture objects. The user-code will be forced to have Direct3D headers included. This lacks of elegance, but, most importantly, can sensibly slow down compilation times.

Many C++ promoters will promptly answer that there are ways around this. Like, for example, building a hidden base class that the user-code sees as a pointer (thanks to forward class declaration). This however adds more work to do, possibly more include files… takes time on the programmer, and, personally, makes me feel like my code is not tidy.
My apartment often ends up being messy, but my code, I really want that nice and simple. I need a streamlined way to write code that looks good.

Posted by Davide Pasca in Uncategorized

This entry was posted on Tuesday, August 16th, 2005 at 2:00 am and is filed under Uncategorized. You can follow any responses to this entry through the comments RSS 2.0 feed. You can leave a response, or trackback from your own site.

9 Responses to “Slowly going back to C.. again !”

  1. ragin' lion says:

    Mr. Kaz, have you tried the D Programming Language?

    Oh you haven’t? I haven’t either! 8P It does have some interesting constructs, but (at the moment) I don’t know of any “serious” commercial applications that use the language.

    A lot of the C++ issues you raise are true … it is a pain, but (like I’ve always said) the true “power” lies in using only the language features that are necessary and at least make your code less buggy.

    Depending on the context having a class with the member variables initialized in the initializer list is a lot less buggy than a struct where you have to initialize things “by hand” or the like.

    頑張ってね!

  2. Anonymous says:

    ragin’ lion said…

    “Depending on the context having a class with the member variables initialized in the initializer list is a lot less buggy than a struct where you have to initialize things “by hand” or the like.”

    Oh yeah, rely on the compiler to decide when things are initialized and freed, sure… a lot safer than doing it yourself and being in complete control of the order…

  3. ragin' lion says:

    Rince, is that you? 8P

    Anyway, that example you raise is a case in which it may not be wise to do that.

    The example I was thinking about was something like:

    class CVector3f
    {
    public:
    CVector3f()
    :x(0),y(0),(0){}

    float x,y,z;
    };

    rather than:

    struct SVector3f
    {
    float x,y,z;
    };

    SVector3f v0;
    v0.x = v0.y = v0.z = 0.0f;

    No memory allocations there …

    As I mentioned before, “the true ‘power’ lies in using only the language features that are necessary…”

    If (based on your design needs) certain language features aren’t needed, don’t use it. Less is sometimes better.

    I’m not trying to make arguments that “C++ is superior to C” or vice versa. To me, a programming language is a tool to get some task done. If C works great for the job, do it in C. In my case C++ has been very useful for the projects I’ve worked on and I really don’t have too many complaints at this point. Yeah, it was a pain to learn and deal with initially, but looking back, it’s definately worth it.

    C99/C9X has some nice improvements to the C language. Perhaps those new features/improvements might be what you need rather than what’s in C++?

  4. rince says:

    Funny that you mention that particular example, in one of the previous projects that I’ve worked on we have something like that for the math library, so all vectors and matrices were being initialized to 0’s ‘behind the scene’, and then guess what showed up at the top of CPU usage during performance profiling?

    All the vector and matrix constructors!

    So your example just further proves my point. If I want to set a vector or a matrix to 0 then force me do it manually when I need it and dont hide it away from me!! =)

  5. ragin' lion says:

    Was that your anonymous post rince? 8P I had a feeling that that example would get shot at … but yeah, that very example would be a performance killer.

    You could optionally do this:

    class CVector3f
    {
    public:
    CVector3f(){}
    CVector3f( float _x, float _y, float _z )
    :x(_x),y(_y),z(_z){}

    float x,y,z;
    };

    I had ran into situations where these bugs would pop up because of uninitialized data … that was annoying. For vector initialization the above style should be ok, for matrices, it’s a bad idea (especially if you’re skinning or the like).

    But I think you get the point I’m trying to make, right? 8P

    Hopefully some newer, better language than C & C++ will emerge eventually.

  6. Davide Pasca says:

    When performance comes into play, OOP can be a real pain. That’s what I experienced with Java. Where every vector wanted to be an object (ouch).

    The safe initialization is useful and spares from bugs (in C I normally do a memset() or so), however it can be a problem. Actually the constructor for the 3D vector thing was also my biggest issue with C++ a decade ago, when I first tried it with the Borland compiler (would do something even with no destructor !).
    Nowadays I think that one can just avoid placing the costructor and destructor, to be sure that a structure can be used just as an interface to a chunk of memory (what’s needed for performance).

    In the end, I guess a distinction has to be made between what should be an object and what shouldn’t.
    There are classes that don’t need multiple instances, then there are classes that need multiple instances but not so many of them, then there are classes that are instanced so many times that the issue becomes time critical.

    OOP will do for the first two cases, but for the third one.. better not get fancy.

  7. ragin' lion says:

    Kaz, it sounds like you’re seeing the point(s) I was trying to make. Perhaps my English isn’t so good anymore these days. It’s a little tricky explain things now in English. 日本語で書きましょうか。 8)

    Which C++ compiler are you currently using? For sure, the C++ compiler technology has greatly improved. I’m not sure which is the best, but it seems that gcc is on the top-10 list.

    Microsoft’s Visual Studio 2005 seems to have some really nice and modern abilities (the XBox360 compiler suite might have similar functionality). Not sure what’s on PS2 … For PS3, it will probably be some variant of gcc since Sony now owns SN Systems.

    Inside the C++ Object Model has a nice overview of what’s going on behind the scenes. It’s dry reading at times, but you’ll realize what and what not to do depending on the design needs of your situation.

  8. rince says:

    Well the compromise that works for me is using the ’static’ keyword a lot and avoiding inheritance, templates, operator overriding. By doing that I seem to inheritantly avoid all the undesireable c++ issues. If I get a bug in my code then it is always due to ‘normal’ causes like un-initialized variables, memory overwrites, incorrect logic, etc… and those are by nature isolated, identifiable and can be fixed without affecting the scope of the rest of the project.

    I think that by declaring everything static I am compliant with the OOP principles by the virtue of all my data and code being local to a particular module.

  9. Davide Pasca says:

    Ragin: 説明のための、日本語の方がいいと言う意味ですか?どうぞ…(^.^)

    Rince: I think that that’s more or less modular programming. Which is what is needed in most cases. However it has earned a bad name because it’s an old paradigm which doesn’t really propose a strong set of rules and concepts like OOP does.
    Strangely enough OOP throught C++ goes against that basic concept of modular/black-box programming, by making everything public.

    Generally I’d say that most code doesn’t need to belong to any object (one instance). Then, perhaps one may need multiple instances of a module, and things can pretty much stay the same, just by adding a context switch function.

    So, instead of having:

    mycontext.DrawLine();
    mycontext.DrawCircle();

    ..one can do..

    SetContext( mycontext );
    DrawLine();
    DrawCircle();

    The added benefit is that the second system actually pushes for explicit namespaces. So one will have:

    MyLib_SetContext( mycontext );
    MyLib_DrawLine();
    MyLib_DrawCircle();

    ..which I think I generally much more clear, while not taking anymore space than the OO version.

    As far as inheritance goes.. I can see it useful in cases in which one uses virtual methods. Avoids some hand made switches.. however I’m still with the fact that most code doesn’t really need all those features.

    Templates came in handy for variable sized arrays. They could handle my trees too, however the implementations I saw, didn’t impress me with performance as I generally wish to have the node pointers directly into my node structure, not wrapped around it ..like for the implementations that I could find around.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>