Compare version numbers I am wondering if there is any way to meaningfully shorten the chain of conditionals used here to compare two versions. struct VERSIONCODE represents a version number of the form major.minor.revision and CompareVersions returns EQUAL if they're equal; LHS_NEWER if vLHS is newer, and RHS_NEWER if vRHS is newer. 

typedef enum
{
    EQUAL = 0,
    LHS_NEWER,
    RHS_NEWER
} ECOMPARISON;

// Specifically not named "VERSION" to avoid conflicting with common names from third-party libraries etc.
typedef struct
{
    int nMajor;
    int nMinor;
    int nRev;
} VERSIONCODE;

ECOMPARISON CompareVersions(VERSIONCODE vLHS, VERSIONCODE vRHS)
{
    if (vLHS.nMajor &gt; vRHS.nMajor)
    {
        return LHS_NEWER;
    }
    else if (vLHS.nMajor &lt; vRHS.nMajor)
    {
        return RHS_NEWER;
    }
    else// if (vLHS.nMajor == vRHS.nMajor)
    {
        if (vLHS.nMinor &gt; vRHS.nMinor)
        {
            return LHS_NEWER;
        }
        else if (vLHS.nMinor &lt; vRHS.nMinor)
        {
            return RHS_NEWER;
        }
        else// if (vLHS.nMinor == vRHS.nMinor)
        {
            if (vLHS.nRev &gt; vRHS.nRev)
            {
                return LHS_NEWER;
            }
            else if (vLHS.nRev &lt; vRHS.nRev)
            {
                return RHS_NEWER;
            }
            else// if(vLHS.nRev == vRHS.nRev)
            {
                return EQUAL;
            }
        }
    }
}
typedef enum
{
    EQUAL = 0,
    LHS_NEWER,
    RHS_NEWER
} ECOMPARISON;



A common convention for three-way comparisons is that of strcmp() - return any negative value if the first argument is less than the second, zero if equal, and positive if greater.

If we take that approach, and if we can ensure that the version values are small enough to avoid integer overflow, we can simplify the comparison to just:

int CompareVersions(VERSIONCODE a, VERSIONCODE b)
{
    int diff = a.nMajor - b.nMajor;
    if (diff) return diff;
    diff = a.nMinor - b.nMinor;
    if (diff) return diff;
    return a.nRev - b.nRev;
}


If we can't ensure overflow won't happen, or if we absolutely must return fixed values, we'll need to convert those subtractions into calls to a custom comparison function - perhaps like this:

int compare_int(int a, int b)
{
    /* standard idiom to return -1, 0 or +1 */
    return (a &gt; b) - (b &gt; a);
}




The naming can be improved.  Most C conventions use ALL_UPPERCASE only for macros, to call attention to their difference from C code.  And most authorities discourage prefixes like the n and v used at the start of variable and member names - I encourage you to research "Hungarian notation" and understand the arguments.