views:

347

answers:

5

Hi, When working in cross-platform project, most probably you will encounter a lot of #ifdef blocks in the code. This is actually very annoying and makes it hard to read the code.

I wonder if there's a way to hide those non-related ifdef blocks? I'm using Visual Studio 2005.

For example, if you have this code:

#ifdef _PC_
do a
#else
do b
#endif

if _PC_ is defined, the tool/plug-in should only show this:

do A
A: 

Just use the following preprocessor directive:

#region IfDef
    #ifdef PC
        doSomethingCalledA();
    #else
        doSomethingCalledB();
    #endif
#endregion
Lucas McCoy
the problem is I have to do that for every files..
tep
Oh well, keep it in mind for your next project ;-)
Lucas McCoy
+1  A: 

The cleanest method I've see (and used) is to use the Strategy Pattern, whereby you can abstract out the platform specific code into a separate strategy class.

eg.

class MyAbstractClass
{
    static MyAbstractClass Create()
    {
        #ifdef win32
        return new WindowsClass(); // this could be a shared_ptr
        #else
        return new PosixClass();
        #endif
    }
    virtual method MyMethod() = 0;
}

// windows_class.cpp
class WindowsClass : public MyAbstractClass
{
    virtual method MyMethod()
    {
        // platform specific code here
    }
}

// posix_class.cpp
class PosixClass : public MyAbstractClass
{
    virtual method MyMethod()
    {
        // platform specific code here
    }
}
Alan
+2  A: 

While my answer isn't exactly what you're looking for, it's the best I know of.

In Visual Studio 2005 it may be possible to use the outlining tool to collapse the unused part of an #ifdef block.

Another idea that comes to mind is breaking off OS specific code into their own files, and using a master file containing the #ifdef blocks and significant parts (i.e. complete declarations) of code that don't change across platforms.

Yet another thing that comes to mind is simply grouping the code for conditional blocks where ever possible. There are many situations in which code order might not matter as much, and you could group that code together.

The other thing that could be done if you only wanted to use the file as reference material is to run the file through a preprocessor that only processes conditional blocks and ignores anything not required to process the conditional blocks.

A: 

Set up a solution for each platform you are working on, with the appropriate macros defined in each. Include the source files in all of the solution. Then go through and collapse the sections of code that do not match the platform for the current solution.

Visual Studio will save your collapsed section settings per solution, so you will see different expanded code depending which project you open. I think this is stored in the *.suo files.

emddudley
A: 

I would suggest against doing what you have asked about. Hiding the fact that your code is multi-platform could easily lead to you, or someone else, not realizing the code they are touching needs to be modified for each platform.

For example, what if you add a line right after the do A line? How do you tell if it goes inside or outside the block? That new line you add could also needs an appropriate alternate line in the other section. Or, if it goes outside the block, you could break the other version without even knowing it.

It may seem inconvenient, but that's the way the language is. Its best to get used to the language's display the way it is designed and the same way everyone else uses it rather than try to hack around things to your preferences.

Coder