{"id":429,"date":"2014-08-02T08:48:37","date_gmt":"2014-08-02T14:48:37","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=429"},"modified":"2014-08-02T09:06:38","modified_gmt":"2014-08-02T15:06:38","slug":"did-you-mean-clang-compiler","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/did-you-mean-clang-compiler\/","title":{"rendered":"Did you mean &#8216;clang&#8217; compiler?"},"content":{"rendered":"<p>One of the many cool features of Google is the <em>Did you mean<\/em> phrase suggested if you fat-fingered your search keywords.  Go ahead, search for the <a href=\"https:\/\/www.google.com\/?gws_rd=ssl#q=clong+compiler\">clong compiler<\/a>.  Google says, yeah, we think you might have meant <i>clang<\/i> compiler.  Thanks Google!<\/p>\n<p>While working one day with some OpenCV code (I&#8217;ll blog about that some day, when I know what I&#8217;m doing), I noticed I had mistyped <code>cvNamedWindow<\/code> as <code>cvNameWindow<\/code> and clang replied:<\/p>\n<pre>\r\nmotion.cpp:12:3: error: use of undeclared identifier 'cvNameWindow'; did you mean 'cvNamedWindow'?\r\n<\/pre>\n<p>Well, isn&#8217;t that cool?  Intrigued I decided to see what gcc would respond with given some typos, and then compare it to clang. <\/p>\n<p>To enable a quick illustration I&#8217;m going to use <code>g++<\/code> and <code>clang++<\/code>.<\/p>\n<p><code>mathr.h<\/code><br \/>\n[c]<br \/>\nint addTwoInts(int a, int b);<br \/>\nint addThreeInts(int a, int b, int c);<br \/>\n[\/c]<\/p>\n<p><code>mathr.c<\/code><br \/>\n[c]<br \/>\nint addTwoInts(int a, int b) { return a + b; }<br \/>\nint addThreeInts(int a, int b, int c) { return a + b + c; }<br \/>\n[\/c]<\/p>\n<p><code>umath.c<\/code><br \/>\n[c]<br \/>\n#include &quot;mathr.h&quot;<br \/>\nint main(void) {<br \/>\n  addTwInts(4, 5);<br \/>\n}<br \/>\n[\/c]<\/p>\n<p>Notice the <code>addTwInts<\/code> function call.  Obviously I meant <code>addTwoInts<\/code>.<\/p>\n<p>Compiling with <code>g++-4.8<\/code> gives <\/p>\n<pre>\r\ng++-4.8 -c umath.c\r\numath.c: In function 'int main()':\r\numath.c:4:17: error: 'addTwInts' was not declared in this scope\r\n   addTwInts(4, 5);\r\n                 ^\r\nmake: *** [umath.o] Error 1\r\n<\/pre>\n<p>Okay, <code>addTwInts<\/code> not declared in this scope.  Since this is a <i>really<\/i> simple example I know where I went wrong.  But, take a look at what <code>clang++<\/code> can tell me:<\/p>\n<pre>\r\nclang++ -c umath.c\r\nclang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated\r\numath.c:4:3: error: use of undeclared identifier 'addTwInts'; did you mean\r\n      'addTwoInts'?\r\n  addTwInts(4, 5);\r\n  ^~~~~~~~~\r\n  addTwoInts\r\n.\/mathr.h:1:5: note: 'addTwoInts' declared here\r\nint addTwoInts(int a, int b);\r\n    ^\r\n1 error generated.\r\n<\/pre>\n<p>Nice!  Yes, I did mean <code>addTwoInts<\/code>!<\/p>\n<p>Searching on Google led me to <a href=\"https:\/\/twitter.com\/clattner_llvm\">Chris Lattner&#8217;s<\/a> <a href=\"http:\/\/blog.llvm.org\/2010\/04\/amazing-feats-of-clang-error-recovery.html\">2010 article<\/a> on Clang&#8217;s neat error recovery features, and there&#8217;s more than just the spell-checking-suggestion-engine.<\/p>\n<p>Clang uses the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Levenshtein_distance\">Levenshtein distance<\/a> algorithm for determining possible corrections to typos.  If you notice, <code>addTwInts<\/code> is just 1 character away (an insertion) from <code>addTwoInts<\/code>, and Clang is able to recognize that and make the suggestion.<\/p>\n<p>Of course there are limits.  Substituting <code>addTwInts<\/code> with <code>addInts<\/code> results in:<\/p>\n<pre>\r\numath.c:4:3: error: use of undeclared identifier 'addInts'\r\n  addInts(4, 5);\r\n<\/pre>\n<p>The distance is 3 inserts from <code>addTwoInts<\/code> and 4 inserts from <code>addThreeInts<\/code>.  What&#8217;s interesting however is that a &#8220;strong match&#8221; (not a technical term!) will boost Clang&#8217;s ability to make a suggestion.  For example, you can change <code>addTwoInts<\/code> to <code>addTwoInts_____<\/code> (your underscore key was stuck that day), and Clang will still make the suggestion &#8220;<code>use of undeclared identifier 'addTwoInts_____'; did you mean 'addTwoInts'?<\/code>&#8221;  Add another underscore (for a total of 6) and you are back to <code>use of undeclared identifier<\/code> with no suggestions.  To quickly calculate the Levenshtein distance of two arbitrary strings, you can try a <a href=\"http:\/\/planetcalc.com\/1721\/\">online Levenshtein distance calculator<\/a>.<\/p>\n<p>I&#8217;m currently only using Clang on my Mac, and the <a href=\"http:\/\/clang.llvm.org\/docs\/UsersManual.html#controlling-errors-and-warnings\">diagnostics features<\/a> work for C, C++, Objective-C, and of course, Swift.  I&#8217;m definitely looking forward to using Clang on Linux where GCC has been the only game in town for decades.  Of course, recognizing the rising adoption of Clang has led to significant <a href=\"https:\/\/gcc.gnu.org\/wiki\/ClangDiagnosticsComparison\">improvements in GCC&#8217;s diagnostics<\/a>.  Only time will tell if GCC will remain the premier compiler on Linux systems (sorry, <i>GNU\/Linux<\/i>.  *smirk*).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the many cool features of Google is the Did you mean phrase suggested if you fat-fingered your search keywords. Go ahead, search for the clong compiler. Google says, yeah, we think you might have meant clang compiler. Thanks Google! While working one day with some OpenCV code (I&#8217;ll blog about that some day, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-429","post","type-post","status-publish","format-standard","hentry","category-miscellaneous"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/429"}],"collection":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/comments?post=429"}],"version-history":[{"count":13,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/429\/revisions"}],"predecessor-version":[{"id":443,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/429\/revisions\/443"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=429"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=429"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=429"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}