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  
    //...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  
    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