7 ms·
C++ at Google: Here Be Dragons
- hsmyers 15y agoCLint meet CLang and the better for it. Although if I read correctly between the lines, there might be a little trouble getting the engineers to buy in :) Every met anyone who could actually make it all the way through CLint with all warnings on! Enough to drive you crazy!
- matthavener 15y agoI wonder if this is an indication that google is moving to clang for compiling (and not just diagnostic tools). If that's true, maybe this is another nail in the coffin for gcc? I see apple and google behind llvm/clang, who's behind gcc? Nobody?
- wmobit 15y agoGoogle has said before they didn't use Clang and LLVM because of performance issues. GCC is far from dead, and probably never will. Clang generated code is still typically 10-20% slower than GCC. Lots of companies work on GCC, including Google, Intel, AMD, IBM, Red Hat and others.
- irons 15y agoApple's been pushing developers toward LLVM for several years, and is bound to make it an app store requirement at some point. I've observed no such 10-20% slowdown on iOS, which is more CPU-constrained than most realms. Typically, LLVM-generated code is equivalent to or faster than gcc. Sometimes it's much faster.
- loup-vaillant 15y agoJust a guess: couldn't be an x86(-64) vs ARM thing? Like GCC being better on x86, and LLVM on par with it on ARM? Or maybe they tuned the compiler for the iDevices?
- DanielRibeiro 15y agoPeople forget that AOT can only get you so far. JIT not only has all the info the AOT mechanism has, but also has real runtime fact based data, and can do wonders with it.
- chancho 15y agoFor the sake of argument: What is an example of an optimization that a JIT compiler can make that a AOT compiler cannot? If the developer is able to profile the application on typical end-user workloads, don't profile-guided optimizations provide the same benefit as JIT runtime profiling? Why can't an AOT compiler just consider every path a "hot" path? Last but not least: Got any benchmarks?
- DanielRibeiro 15y agoFor one: JIT can do polymorphic inline caching (you can read more about from Google's senior vice president of operations Urs Hölzle[1]), while AOT can't. Wikipedia gives a few more[2]: runtime profile-guided optimizations and pseudo-constant propagation [1] http://research.google.com/pubs/author79.html http://research.google.com/pubs/author79.html [2] http://en.wikipedia.org/wiki/AOT_compiler http://en.wikipedia.org/wiki/AOT_compiler
- jonhohle 15y agoThe Polymorphic Inline Caching paper refers to AOT compiling with runtime hints. In the case of non-dynamic languages like C and C++ that clang generally targets, are there other examples of where JIT would make things possible that are not possible in AOT?
- ori_b 15y agoProfile guided optimizations that are relevant for the specific invocation of the program. Loop optimization based on invocation parameters for that specific run of the program. Hard-coding in the jump target address for calling functions from dynamically loaded libraries (can't do that AOT, because if the library is replaced, the symbol offsets change). Optimizing for the specific processor you're running on, as opposed to being forced to compile for a lowest common denominator. A whole bunch of other small things like that.
- ANH 15y agoI've seen this "10-20% slower" meme several times, but I've also read several accounts of 10-20% faster runtime performance. All I know for sure is I compiled my codebase with Clang for the first time yesterday and the compilation time was absurdly short. I thought the compiler was broken. And it enables excellent tools like clang_complete for Vim code completion.
- MBlume 15y agoWoah, let's not conflate compilation-speed with runtime-speed...
- stephen_g 15y agoIt depends on the code - while GCC, being more mature, is typically better at most optimisations, there are a few cases where Clang produces code that is a fair bit faster. Over time, as Clang gets more mature, it will become more and more on par (or better) than GCC.
- jrockway 15y agowho's behind gcc? Nobody? I hear there's this kernel called Linux that depends heavily on GCC.
- xorglorb 15y agoClang has been able to build Linux since October of last year. http://lists.cs.uiuc.edu/pipermail/cfe-dev/2010-October/011711.html http://lists.cs.uiuc.edu/pipermail/cfe-dev/2010-October/0117...
- tedunangst 15y agoAnd Linus's feelings about that relationship are...?
- wisty 15y agoPragmatic, I would guess. "Quite frankly, I'd like there to be more competition in the open source compiler game, and that might cause some upheavals, but on the whole, gcc actually does a pretty damn good job." http://kerneltrap.org/Linux/Volatile_Performance http://kerneltrap.org/Linux/Volatile_Performance
- ch0wn 15y agoClang has support for a lot of gcc extensions: http://clang.llvm.org/docs/LanguageExtensions.html http://clang.llvm.org/docs/LanguageExtensions.html
- roel_v 15y agoBut why would the kernel depend on gcc? Are there so many gcc-isms in there that would be hard to replicate on other compilers?
- deleted 15y ago[deleted]
- adestefan 15y agoThe biggest one is (was?) the use of GNU variable length arrays. The GNU extension has different syntax than C99's variable length arrays. There are also instances of __attributes__ on platform specific code.
- marshray 15y agoGCC has enabled Apple and Google far more than the other way around. Clang and LLVM sound like great projects, but I hardly think GCC is heading for the grave anytime soon. http://gcc.gnu.org/releases.html#timeline http://gcc.gnu.org/releases.html#timeline http://www.gnu.org/philosophy/pragmatic.html http://www.gnu.org/philosophy/pragmatic.html (see part about Objective C)
- siphr 15y agoWell written! The simple bugs that it seems to detect are fairly high frequency so it should therefore improve overall code quality. Looking forward to playing around with this in my spare time.
- Natsu 15y agoI haven't even done any C++ for a while, but reading those other articles on HN about undefined behavior in C made the example bugs in this article really jump out at me.
- anonymous246 15y agoI wonder how their checks compare to Coverity's and QAC++'s. I have a passing acquaintance with both, and I'm almost certain both would have caught the three bugs listed on that page.
- chandlerc 15y agoI would expect many of these tools to catch these types of bugs. The challenging thing for us has been to catch only bugs, and to catch them very fast during normal compilation. A lot of the static analyses we've looked into (and I'm hoping for more detailed blog posts about that in the future) find plenty of bugs, but also find lots of non-bugs. Combine that with being too slow to run during the normal build, and you can't break the build when such a bug is found. I think one of the most interesting aspects of this is how we catch the bugs early, and force developers to fix them immediately by breaking the build.
- mcbain 15y agoStatic analysis is a great tool - Clang's isn't too bad - but it isn't the right one to drop into a normal workflow. We still develop using GCC - for our use case Clang performance isn't there yet - but have our continuous integration system perform Clang builds (as well as other platform/compiler variants, with unit+regression tests, etc.) so we miss out on the immediate build breakage that you mention, but do find out within ~30 mins if someone slipped up.
- spitfire 15y agoThese sort of articles (and the attendant comments about false positives) always scream out for Ada to me. It's a language designed by a calm, careful thinker back in the 80's for life critical programs. It has everything Java and C++ have except the vast number of undefined states and it's designed for static analysis. By designed I mean, there are formal verifiers and the NSA has used it in a test security system. Plus the compiled code is pretty fast. So if you're feeling the need to reduce your workload take a look at it, you might be surprised.
- 15y ago
- mayoff 15y agoWhen will they enhance it to flag the other error in this line: long kMaxDiskSpace = 10 << 30; // Thirty gigs ought to be enough for anybody. 10<<30 is ten gigs, not thirty gigs.
- chandlerc 15y agoDoh! Good catch, comment updated. =[ Maybe we do need Clang-for-comments as well as Clang-for-C++ code.... ;]
- nikki9696 15y agoAnd the error says it's an int, but it's declared long. Am I missing something about long in C++ not being 64 bits?
- chandlerc 15y agoThat's the whole point. =] This is a surprising aspect of C++: the shift expression doesn't have the type of the declared variable. The integer literals we are shifting are of 'int' type, and the shift occurs at that type (based on the usual arithmetic conversions). There is stack overflow question with explanations and a good blog post here about it: http://stackoverflow.com/questions/836544/usual-arithmetic-conversion-a-better-set-of-rules http://stackoverflow.com/questions/836544/usual-arithmetic-c... http://blogs.msdn.com/b/oldnewthing/archive/2004/03/10/87247.aspx http://blogs.msdn.com/b/oldnewthing/archive/2004/03/10/87247... Also, you can look through the C++98 standard to understand all the details. Relevant sections are [expr]p9 and [expr.shift].
- DarkShikari 15y agolong is 32-bit on x86_32 Linux, 64-bit on x86_64 Linux, and 32-bit on x86_64 Windows.
- DerekL 15y agoThe left operand is an int, so the result of the shift expression is an int. The fact that the shift expression is used to initialize a long is not relevant.
- timr 15y agoTo me, the most remarkable thing about this post is that when the rest of the world is falling in love with the "power" of weak typing systems, Google is going the other way.
- profquail 15y agothe rest of the world is falling in love with the "power" of weak typing systems Really? I'd argue the exact opposite -- with F# and Scala (and some others) on the rise, I think there are plenty of people who are fed up with weak/dynamic typing and want to take advantage of building programs with strong type systems. At the very least, it seems that the programming world is becoming much more polarized. Anecdotally, it seems that every developer I know is either a proponent of strong/static typing or weak/dynamic typing -- but I don't know anyone that's just sitting on the fence.
- undees 15y agoThe term "strong" appears overloaded here. A language can be dynamically typed, but still have strong typing (in the sense that the language, whether at compile time or runtime, enforces what operations are allowed on a particular value).
- daniel-cussen 15y agoThis is true. Lisp compiles beautifully if you put the work into making it do so, and this work can be automated with macros.
- michaelcampbell 15y agoI'm a fence-sitter, but as you note, it's unlikely you know me. I do find that I'm starting to lean more on the strong/static side lately, but that might be because professionally I write financial institution software which tends to be big, and I want as much checked as early and as thoroughly as possible. For fun hobby stuff, I love dynamic languages where I can produce quite a bit of functionality in a very short (if dangerous) time and rely on a set of tests to keep it all managed.
- archangel_one 15y agoThe article implies to me that the third bug (passing 0.5 to sleep() ) is not caught by gcc. Does anyone know if this is the case? It doesn't seem excessively hard to produce a warning about shortening like that - the first two seem more subtle, but that one less so. I don't have gcc on this machine to check it, but VC++ certainly does emit a warning for that kind of thing.
- chandlerc 15y agoGCC definitely has a warning for 0.5 -> int (likely -Wconversion, but I've not checked). It also has a warning for setting a pointer to "false" (-Wconversion-null). However, turning that warning on in a codebase where every warning breaks the build was challenging because of false positives. We're able to remove false positives and narrow the scope of the warning to just the buggy code in many cases with Clang, and that allows us to turn these warnings on much more aggressively.
- lurker19 15y agoWhen is assigning a pointer to be boolean false intentional and correct?
- cpeterso 15y agoI think the -Wconversion-null warnings are the other way around: int i = NULL; Because of C++'s conflation of NULL and 0 (and now C++0x's nullptr).
- chandlerc 15y agoMost of the cases we ran into were metaprogramming techniques which test whether an expression is a valid null pointer constants. These got innocently applied to 'false' and trigger the warning needlessly.
- koenigdavidmj 15y agoDone that before...had a variable that was formerly an int: int foo = 0; But got changed into a non-integral type: Thing foo = 0; Turns out Thing had a copy constructor roughly like: Thing::Thing(Thing* old) : field(old->field) { } Needless to say, my program was not very happy.
- SwellJoe 15y agoI haven't worked in C (or C++) heavily in about 6 years, since I shut down my prior company and stopped working on Squid or having to look at kernel code. But, these errors are simply beautiful, and make me have vague longings to work on C projects again (I'm sure I'll get over those longings soon). These are the kinds of mistakes I made all the time when working in C, and the kind of thing that made coding extremely tedious...it feels like magic when the compiler catches them with such clear and concise warnings. For whatever reason, I didn't use lint very much back then, as I guess I always assumed I knew what I was doing and that the compiler would catch mistakes. Having this capability in the compiler is pretty cool and brings C/C++ a small step closer to working in higher level languages, is what I think I'm trying to say here.
- jamesaguilar 15y ago> I'm sure I'll get over those longings soon Your getting over those longings will probably coincide with when you start working with C++ again.
- stephen_g 15y ago"Having this capability in the compiler is pretty cool and brings C/C++ a small step closer to working in higher level languages" C++0x is another (much bigger, in my opinion) step that makes C++ a lot easier to program. It's not quite as easy as higher level languages, but far closer than before, and the performance gains over most other languages make it worth using.
- roel_v 15y agoI agree. Lately I've been writing substantial amounts of 'higher level' code again, and I find myself writing many checks for the types of variables (as members or arguments), return values, contents of containers, in situations where one may make inadvertent conversions etc. I'm thinking that much of the time I spend on that would have cost me less time if I could have just specified them in the code and the compiler/runtime would check them for me, like in C++. Of course writing unit tests helps too, but in C++ the compiler catches these things easily. And I haven't had the desire to use a variant in years so the advantages of having a 'variable' that can be of any type is quite minimal, imo. The auto keyword in C++0x will make a large portion of the tedious parts of strong typing in C++ go away, too. IMO thinks like type hinting in PHP are absolutely steps in the right direction. There is room for both 'scripting' and 'compiled' languages, but good support for indicating and checking the expected or required types in scripting languages helps tremendously in proactively validating programs.
- RandyHelzerman 15y agoIs there anything more to this than "um, we, like, use warnings and stuff". Worthless. If anybody else but somebody from google would have posted this on their blog, it would have been justly and summarily ignored.
- mleonhard 15y agoEclipse highlights these kinds of bugs in java code. It saves me a lot of time.