Compare a given version number in the form major.minor.build.patch and see if one is less than the other #include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;stdbool.h&gt;

typedef int STATUS;
#define ERROR -1
#define OKAY 0

struct version
{
    unsigned char major;
    unsigned char minor;
    unsigned char build;
    unsigned char patch;
};
STATUS is_less_than(struct version * original, struct version *compared, bool *result)
{
    if(original == NULL || compared == NULL || result == NULL)
    {
        result = NULL;
        return ERROR;
    }
    *result = false;

    if(original-&gt;major &lt; compared-&gt;major)
    {
        *result = true;
    }
    else if(original-&gt;major == compared-&gt;major) // else if the major &gt;= major
        {

            if(original-&gt;minor &lt; compared-&gt;minor)
            {
                *result = true;
            }
            else if(original-&gt;minor == compared-&gt;minor)
            {
                if(original-&gt;build &lt; compared-&gt;build)
                {
                    *result = true;
                }
                else if(original-&gt;build == compared-&gt;build)
                {
                    if(original-&gt;patch &lt; compared-&gt;patch)
                    {
                        *result = true;
                    }
                    else if(original-&gt;patch == compared-&gt;patch)
                    {
                        *result = false;
                    }
                }
            }
        }


    return OKAY;

}


Is there a cleaner way to do this?
Yes, there is a cleaner way:

if (a.major != b.major) {
    *result = a.major &lt; b.major;
} else if (a.minor != b.minor) {
    *result = a.minor &lt; b.minor;
} else if (a.patch != b.patch) {
    *result = a.patch &lt; b.patch;
} else {
    *result = a.build &lt; b.build;
}
return OKAY;


I reordered patch to come before build since that's how it is usually done. If your version scheme is different from this, good luck.

Instead of unsigned char I would choose uint32_t so that your code can handle versions like 1.0.20190415. If you need to handle version numbers with millisecond timestamps, each version component would need to be uint64_t.