Thursday, December 4, 2014

Readability Snippet #1 : Pass by reference

When passing parameters by reference in C++ you basically have 2 options to do so:

Snippet #1: Pass the reference of the variable you want to pass to a function
Example:

 void foo(int& myIntParameter)  
 {  
   //... do something with myIntParameter  
 }  
 int main(int argc, char** argv)  
 {  
   int myIntVariable = 5;  
   foo(myIntVariable);  
 }  

Snippet #2: Pass the address of the variable you want to pass to a function
Example:

 void foo(int* myIntParameter)  
 {  
   if (myIntParameter)  
   {  
    //... do something with myIntParameter  
   }  
 }  
 int main(int argc, char** argv)  
 {  
   int myIntVariable = 5;  
   foo(&myIntVariable);  
 }  


Now, when reading code where variables get passed by reference like in snippet #1, it is actually not visible at first if the variable gets passed by value or passed by reference as the calling convention for both are actually the same. One had to look up the actual function definition by finding out whether the variable gets passed by reference or value. I consider this tedious as you always have to browse through your sourcecode to find out if a function call could *potentially* alter your variables value.

In this post, I'd like to present a way to make call by reference function calls more readable.

Snippet #3: Creating macro identifier for call by reference via actual variable reference

When using call by reference like in snippet #1, you could define some kind of macro qualifier that you can add to the function call.

Example:
 #define ref  
 void foo(int& myIntParameter)  
 {  
 }  
 int main(int argc, char** argv)  
 {  
   int myIntVariable = 5;  
   foo(ref myIntVariable);  
 }  

Unfortunately this has the disadvantage of not doing any compile-time checks.

------

Another solution would be to just don't use call by reference calls like in snippet #1 and just pass the address of the variable you want to modify. This method however usually introduces some sanity checks like null pointer checks etc. So you basically trade readability with compactness.

Monday, June 2, 2014

Weekend prototype #1 C/C++ Enum Parsing

This weekend I prototyped a command line tool written in Lua for parsing C/C++ files to get a list of enums used in the codebase that has been parsed.

Once the codebase has been parsed, the tool will create a new header file (or rewrite an existing one) and save all exported enums as string arrays.

Consider the following C/C++ Header:
 #ifndef _Transform_h_  
 #define _Transform_h_  
 class Transform {  
    enum TransformSource {  
      TS_NONE = 0,  
      TS_PARENT,  
      TS_SCENE,  
      TS_COUNT  
    };   
    Transform();  
    ~Transform();  
    //etc...  
 };  
 #endif //_Transform_h_  

If this file would serve as input to the enum parsing tool, the tool would create the following output:
 const char* TransformSourceStr[] = {  
    "TS_NONE",  
    "TS_PARENT",  
    "TS_SCENE",  
    "TS_COUNT"  
 };   

More informations about the tool and the source code can be found in the BitBucket repository.

Thursday, February 6, 2014

C++ Build Preprocessing Thoughts

Something that's been on my mind lately is how you could automatize many otherwise tedious and repetitive programming tasks by using custom build preprocessing tools.

If you're familiar with Qt's meta object compiler (moc) then you should have a good understanding of what I'm trying to talk about in this post.

When I first thought of useful C/C++ build preprocessing steps I was adding reflection and serialization to my engine.

Serialization, for instance, was just filling out a virtual serialize() function, where each member variable of a class was written to a binary stream.

Basically it was like this:

 Example::serialize(Stream& p_Stream)  
 {  
    p_Stream << m_Value1;  
    p_Stream << m_Value2;  
    p_Stream << m_Value3;  
    //custom class  
    m_Value4->serialize(p_Stream);  
    //...and so on  
 }  

As you can imagine, this got tedious and boring pretty quick...And that was when I though about a more elegant solution for this.

A few days later, build preprocessing came to my mind.

The basic idea is to use some kind of parser-tool (clang anyone? Getting a hang of clang can be pretty tedious, but it will pay off eventually) to parse your C/C++ code and
identify variables by using custom type qualifier. The information you gather by identifying your variables like this can be used to automatically create various function (like the serialize() function in this example)
In my codebase this would look like:

 #define serializable  
 class Example  
 {  
 public:  
    Example();  
    ~Exmaple();  
 private:  
    serializable int m_Value1;  
    serializable float m_Value2;  
    serializable bool m_Value3;  
    serializable CustomClass m_Value4;  
 };  

The tool I build (in lua - still learning how to use clang) scans my codebase for variables with the custom qualifier 'serializable'. It then saves these variables and automatically creates the serialize() function with the information it gathered during the codebase parsing.

This approach saved me various hours of tedious code doublication so far :)

Some more examples I thought of that would make sense would be

  • Code reflection (again using custom qualifiers)
  • Enum <--> String conversion