Clang, a better compiler for C and its derivatives.

If there’s a project that caught my interest lately, it’s Clang, a front-end for the LLVM compiler created as a “drop-in” replacement for gcc. It’s a brand new, state of the art, modern, BSD-licensed open-source compiler that is a lot faster, optimizes more aggressively while using far less memory than the competition. For now, only the C(Yes, at last, a C99 compiler) and Objective C support is complete and are considered “production ready”. C++’s support is still only partial but the situation is improving at a very fast pace. See  http://clang.llvm.org/cxx_status.html for more information about it.

Having a compiler that produces good and optimized code is always welcome but… Is there anything left in it for the programmer? Yes, clang’s static analyzer provides the programmer with clearer, better diagnostic messages. It is also easier to integrate to IDEs and is already doing wonders in Apple’s XCode 3.2. Let’s see what it can do.

For a short example, see this ill-formed code:


#include <stdio.h>

typedef const char *LPCTSTR; /*Let's say they're ugly          */
typedef char *LPSTR;         /*typedefs from some other header */

void print(LPSTR toprint)
{
    printf("%s", toprint)    /*Omitted ';' on purpose*/
}

int main(void)
{
    LPCTSTR a = "Hello";
    LPCTSTR b = "World";
    LPCTSTR c = a + b; /*cannot concatenate strings with operator +*/
    print(c); /*Passing a const char * to a function taking a char * */
    return 0;
}

Let’s compare clang to gcc and cl (Visual C++). All three compiler detect two errors and a warning but let’s see how good are their diagnostics:

First error: Semi-colon missing at the end of line 8

GCC:
test.c: In function ‘print’:
test.c:9: error: expected ‘;’ before ‘}’ token
CL:
...\test.c(9) : error C2143: syntax error : missing ';' before '}'
CLang:
test.c:8:26: error: expected ';' after expression
    printf("%s", toprint)
                         ^
                         ;

Both gcc’s and cl’s diagnostic are wrong, the semi-colon should be placed at the end of line 8. On the other side, clang found that a semi-colon is missing at the 26th character of line 8 and even points it with ^, a really nice improvement.

Second Error: You can’t add two LPCTSTR(const char * in disguise)

GCC:
test.c: In function ‘main’:
test.c:15: error: invalid operands to binary + (have ‘LPCTSTR’ and
           ‘LPCTSTR’)
CL:
...\test.c(15) : error C2110: '+' : cannot add two pointers
CLang:
test.c:15:19: error: invalid operands to binary expression
              ('LPCTSTR' (aka 'char const *') and 'LPCTSTR'
              (aka 'char const *'))
    LPCTSTR c = a + b;
                ~ ^ ~

Now, all three compilers found the error but the diagnostics of gcc and cl are not really helpful, they only tell us that we cannot add two LPCTSTR but doesn’t give us a clue as to why. CLang’s diagnostic message is about the same but also shows us that LPCTSTRs are simply char pointers in disguise and where is the exact source of the problem.

Third Error: Passing a const char * to a function taking char * could be dangerous

GCC:
test.c:16: warning: passing argument 1 of ‘print’ discards
           qualifiers from pointer target type
test.c:6: note: expected ‘LPSTR’ but argument is of type ‘LPCTSTR’
CL:
.../test.c(16) : warning C4090: 'function' : different 'const' qualifiers
CLang:
test.c:16:11: warning: passing 'LPCTSTR' (aka 'char const *') discards
              qualifiers, expected 'LPSTR' (aka 'char *')
    print(c);
          ^

Now, gcc’s diagnostic is just plain vague, the fact is mentions “pointer target type” can give us a small hint that LPCTSTR might be a pointer but it’s not like “const” is the only possible qualifier in C. cl does a bit better telling us that it’s a constness issue but again, clang is clearly the winner by letting us know that LPCTSTR is in fact a char const * and showing us where is the problem.

Probably that some conservative “elitists” are going to say that gcc or cl diagnostics are fine the way they are but the way I see it, there’s always place for improvement and if a tool like clang can increase my productivity while generating fast and optimized code then… why not? I encourage everyone to at least give it a try( for C and Objective C ) and even contributing to it by improving it’s C++ support.

http://clang.llvm.org

Advertisements

2 comments so far

  1. rmn on

    The diagnostics look awesome! Gotta love the neat ascii pointers below the problematic sourcecode (^).

    Thanks for introducing this. I’ve already heard very good things about LLVM ( it is also used in http://c-to-verilog.com ), and CLang makes it even more appealing.

  2. gf on

    While CLang is clearer, GCC and cl are not wrong on the first error – the ‘;’ just has to appear before the ‘}’.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: