Slashdot Mirror


Developing In C/C++? Why You Should Consider Clang Over GCC (dice.com)

Nerval's Lobster writes: The idea with Clang, a compiler front-end for C, C++, Objective-C++, and Objective-C, and LLVM (a compiler infrastructure) is that you can mix the compiler front-end with a targeted back-end and end up with highly portable and efficient compiler. Clang can perform static analysis of your code, and lets you write tools that give you information about a program. Although many developers prefer developing in C/C++ using GCC, developer David Bolton (in a new Dice article) makes an argument for why you should switch to Clang. While GCC is probably still best when it comes to speed, he argues, Clang is improving release by release, and features tools that developers could find useful.

38 of 255 comments (clear)

  1. Translation by RightwingNutjob · · Score: 2, Insightful

    While GCC is probably still best when it comes to speed, he argues, Clang is improving release by release, and features tools that developers could find useful

    Translation: "network tran--I mean speed is a feature that most of our users don't need, so it's not in our development plan"

    1. Re:Translation by ShanghaiBill · · Score: 5, Informative

      Translation: "network tran--I mean speed is a feature that most of our users don't need, so it's not in our development plan"

      No. Clang produces faster code. What TFA means is that GCC compiles faster. But if slightly faster compiles are that important, just turn off the optimizer, or buy a faster computer. How much time does a modern developer spend waiting for the compiler to finish? For me, it is less than 1%. Far more important is the better error messages, warnings, and static analysis from Clang. Those save me way more time than the speed of the compiler.

    2. Re:Translation by ShanghaiBill · · Score: 4, Informative

      Large applications can take -forever- to compile, even if its not a clean compile.

      Many complaints about slow compiles are due to dysfunctional workflow. You should be using precompiled headers, and set up your makefiles for multiple cores. But most importantly, you should be using TDD to develop and debug code outside of the application. So instead of compiling and linking the entire application repeatedly as you track down a bug, you only integrate after all your unit tests are written and passed in isolation.

      But, anyway, it isn't clear that Gcc actually compiles faster than Clang. Here are some benchmarks, and the results are mixed. Sometimes Clang is faster, sometimes Gcc is faster. For a large app, they would likely be about even in compile time. But Clang would likely generate better code, and almost certainly generate more helpful errors/warnings/analysis.

      I can't see any rational reason to prefer Gcc.

    3. Re:Translation by HiThere · · Score: 2

      If you're dubious about "special compilation", then use GCC to compile clang. (It's not sufficient, but using a different compiler to do the compilation of the compiler is a necessary step.)

      --

      I think we've pushed this "anyone can grow up to be president" thing too far.
    4. Re:Translation by epyT-R · · Score: 2

      No. Sometimes Clang produces faster code. Read the rest of that review.

    5. Re: Translation by Anonymous Coward · · Score: 5, Funny

      And what kind of garbage programmers are you that need to compile the same code multiple times? Write the code correctly the first time and only compile once.

    6. Re:Translation by mikael · · Score: 2

      I've seen cross-compile builds of large code bases of 2 million+ lines take 10 minutes. Change one header file of a low-level module, and the whole stack has to be rebuilt. Just because BaseClassA has had a new boolean flag added, DerivedClassB to DerivedClassJ have to be recompiled along with container classes, interface classes, then the GUI layer with custom widgets, the plugins for third-party editors, the dynamic linked libraries, and finally the application itself.

      --
      Vintage computer adverts: http://www.vintageadbrowser.com/computers-and-software-ads
    7. Re:Translation by Yokaze · · Score: 3

      If you are running into that issue often, consider the Pimpl-pattern.

      As always, C++ doesn't take the decision away from you. If you cannot live with the overhead in runtime from one pointer indirection, you have to live with the other downside.

      From my standpoint and experience, most compile time issues were due to people putting things into the headers out of convenience.
      In order to save some forward declarations or pimpl implementations, things were put into the header, which caused constant recompiles,and long compile times.

      --
      "Between strong and weak, between rich and poor [...], it is freedom which oppresses and the law which sets free"
    8. Re: Translation by kthreadd · · Score: 2

      GCC runs native on Windows. It's maintained by the mingw64 project and works really well.

    9. Re:Translation by Darinbob · · Score: 4, Insightful

      Apple migrated over to Clang, but they left a bastardized GCC in it's place as a "transition". The preprocessor swears up and down that it's GCC but if you use inline assembler it barfs. So it's basically lying. It's a GCC front end and LLVM back-end, and the solution is to manually install a real GCC in its place (easier than porting the code, easier than ifdef OSX vs Linux, etc). And it's a major pain in the ass for new developers to set up a development environment, and inevitably someone eventually screws up their PATH to pick up the broken compiler...

      Anyway screw it. Clang may be ok, but there's production code that assumes GCC, it's cross-platform code so having stability on x86 doesn't necessarily mean anything about all those other CPUs that GCC supports well. Ie, GCC supports ARM, and ARM supports GCC, so if I go to the team and say "hey guys, I'm going to mix things up for a few months and try out a different compiler, things might break unexpectedly but in the long run you might like it, what do you think?" then I won't get positive feedback.

      Until there are drawbacks to GCC there's no much reason to change.

    10. Re:Translation by Darinbob · · Score: 2

      C++ (in GCC at least) is vastly slower than C, for the same input source. That's without doing the complicated stuff. You can speed a lot of with parallel builds, but a lot of people don't set up their build systems to make that easy (just passing -j to a recursive make can break).

      A decade ago I had an 18 hour build. So bad that people would start shouting if someone tweaked a major header file. Much of the slowdown was from the commercial compiler, and part of the slowdown was by using Visual Studio as a build system which called out to the external compiler. Swap to GCC+make and the build times got down to 20 minutes.

      Also for builds, don't forget the continuous builds that are common these days. Any source code change checked in kicks off a build. You want to see the results of that sooner than later, so you don't get the phone call a few hours later asking you to fix the build. Then the nightly builds will often rebuild every permutation of the project which can take a very long time.

    11. Re:Translation by Darinbob · · Score: 2

      Number 1 is important. The primary reason Apple is supporting Clang is that they got a snit over the new GPL license.

      Now Clang/LLVM do work on more than just PC architectures, but there aren't as many developers and users for them compared to GCC users. So the more users you have the more feedback, the more feedback the better the end product. Especially with something like ARM with lots of processor and instruction set variants you really want to make sure you're not inadvertently the beta tester for the compiler support for your chip.

    12. Re: Translation by Darinbob · · Score: 3, Funny

      I keep telling the users that, run the program correctly the first time and you shouldn't have to run it a second time!

    13. Re:Translation by TheRaven64 · · Score: 4, Insightful

      Apple, whose most profitable product lines all include ARM chips, has a large compiler team working on Clang and LLVM. Google, which doesn't ship any ARM products, but does have a huge investment in the ARM ecosystem, also employs a lot of people contributing to LLVM. They contributed most of the ARMv8 back end. ARM also has several large teams working on LLVM (I think that they've largely consolidated them now - they used to have separate C, OpenCL-ARM, and OpenCL-Mali teams all working largely independently on LLVM) and is now (as the other poster says) using LLVM for their proprietary toolchain (which is mostly expensive because of the debugging / tracing tools), so they're contributing a lot. There are a lot more ARM developers working on LLVM than clang. IBM has people working on PowerPC support, Imagination Tech on MIPS support. SPARC is largely volunteers these days, but Oracle seems to be killing SPARC as a thing anyone else might care about.

      --
      I am TheRaven on Soylent News
    14. Re:Translation by TheRaven64 · · Score: 2

      C++. For efficiency, you often need to put small methods in the headers. If they're templates, then you don't have an option if you want to share them between compilation units. Change a template in a header and you can easily trigger recompilation of a few hundred C++ files.

      --
      I am TheRaven on Soylent News
    15. Re: Translation by DrXym · · Score: 2
      It works really well for portable source code and where everything you link to comes from the same compiler. It's not so good if you're trying to link to some dynamic or static lib which was produced for MSVC because memory management and exception handling are incompatible. Unfortunately this happens quite a bit on Windows. IDE support isn't particularly good by comparison to MSVC either, particularly interactive debugging.

      Clang for Windows is taking an approach which is somewhat bizarre but could potentially achieve better compatibility with MSVC - you drop the clang binaries on a system which already has Visual Studio and it compiles code against the same headers and libs. As such it already supports a lot of VC++ extensions, keywords and name mangling. You can even run Visual Studio and develop against clang from there and run MSBuild with clang.

      The flipside, is if you have MSVC installed (a perfectly good compiler suite) then why earth do you need Clang? I think Clang needs to be a standalone package, perhaps using the MingW headers, even if it is capable of using MSVC headers / libs if you have them installed. Then someone can choose what level of compatibility they want.

    16. Re:Translation by Anonymous Coward · · Score: 2, Insightful

      1) Long term Freedom. The importance of which can not and should not be understated.

      Except gcc doesn't give you that. The FSF keeps changing the goalposts on what constitutes "free" software (see GPLv2 vs GPLv3, for instance), and every time they do it, they lose developers who can no longer adapt to their ideology. Clang is FREE. Sure, someone might fork it, someone might embrace&extend it, this does not mean I will in the future be unable to use the Clang code I have on my hard-drive right now. And it's a compiler. It compiles code, to a standard. Lock-in is not an issue.

      You are pushing a concept of theoretical freedom which doesn't even give people the practical freedoms they actually need, against a different concept of freedom which is for all practical considerations completely unencumbered.

      Choose your compiler based on ideology if you like. The computer industry wasn't created on that basis, and doesn't work on that basis.

    17. Re:Translation by fche · · Score: 2

      "Clang is also portable code, which gcc absolutely is not." ... Er, gcc has been portable to cpu architectures and os platforms you probably haven't even heard of, in decades you perhaps weren't even born yet. It's probably one of the most portable pieces of software. (It pays for that in many ways.)

  2. Or compile on everything by Anonymous Coward · · Score: 3, Insightful

    Compile in both. And visual studio too if possible. Enable all warnings. They are all good at identifying different categories of problems and code that compiles cleanly under multiple compilers will prove easier to maintain.

  3. Strongly recommend Clang by Anonymous Coward · · Score: 3, Informative

    I strongly recommend Clang. It's speed is about on par with GCC, but the output and syntax checking is so much better. I tried it a bit a few years back and I have been hooked on Clang since. Using GCC feels like a big step backward now because it's so fussy and its warnings are so cryptic in comparison.

    1. Re:Strongly recommend Clang by flargleblarg · · Score: 2

      Actually, that should compile to a single opcode only if x is a 32-bit unsigned integer.

    2. Re:Strongly recommend Clang by nctritech · · Score: 2

      Assuming 'uint32_t x' and ignoring any needed shuffling to load 'x' into the appropriate processor register, any 32-bit processor with a native bit rotation instruction.

    3. Re:Strongly recommend Clang by Anonymous Coward · · Score: 2, Informative

      $ cat rol3.c

      #include <stdint.h>
      uint32_t rol3(uint32_t x) {
          return (x << 3) | (x >> 29);
      }

      $ gcc -c rol3.c
      $ objdump -d rol3.o

      0000000000000000 <rol3>:
        0: 55 push %rbp
        1: 48 89 e5 mov %rsp,%rbp
        4: 89 7d fc mov %edi,-0x4(%rbp)
        7: 8b 45 fc mov -0x4(%rbp),%eax
        a: c1 c0 03 rol $0x3,%eax
        d: 5d pop %rbp
        e: c3 retq

      $ gcc -O1 -c rol3.c
      $ objdump -d rol3.o

      0000000000000000 <rol3>:
        0: 89 f8 mov %edi,%eax
        2: c1 c0 03 rol $0x3,%eax
        5: c3 retq

      $ clang -c rol3.c
      $ objdump -d rol3.o

      0000000000000000 <rol3>:
        0: 55 push %rbp
        1: 48 89 e5 mov %rsp,%rbp
        4: 89 7d fc mov %edi,-0x4(%rbp)
        7: 8b 7d fc mov -0x4(%rbp),%edi
        a: c1 e7 03 shl $0x3,%edi
        d: 8b 45 fc mov -0x4(%rbp),%eax
        10: c1 e8 1d shr $0x1d,%eax
        13: 09 c7 or %eax,%edi
        15: 89 f8 mov %edi,%eax
        17: 5d pop %rbp
        18: c3 retq

      $ clang -O1 -c rol3.c
      $ objdump -d rol3.o

      0000000000000000 <rol3>:
        0: c1 c7 03 rol $0x3,%edi
        3: 89 f8 mov %edi,%eax
        5: c3 retq

      tl;dr: gcc uses the rol instruction with default -O0, but clang doesn't use it until you turn on -O1.

      Your comment has too few characters per line (currently 18.1).Your comment has too few characters per line (currently 18.7).Your comment has too few characters per line (currently 19.6).Your comment has too few characters per line (currently 20.6).Your comment has too few characters per line (currently 21.6).Your comment has too few characters per line (currently 22.5).

  4. Re:What do they mean by speed? by Chris+Mattern · · Score: 4, Funny

    If I can be modded down for being a troll, can I be modded up for being an orc, or a balrog?

    Nope, those still get you modded down. To be modded up, you'll need to be an elf or a hobbit...

  5. Use both by Anonymous Coward · · Score: 2, Interesting

    To make sure my code is not using any compiler features I compile my code on both.

  6. License by danbob999 · · Score: 2

    Isn't LLVM/clang all about the license (non-GPL)? Otherwise if clang is good, then we should fork it and make a GPL version of it.

    1. Re:License by dmoen · · Score: 4, Informative

      No, LLVM/clang is all about having a superior architecture to GCC, so that a lot of new applications become possible. One of the key ideas is that the optimizer and code generator are libraries with a C++ API. One cool application of this is that you can use the LLVM library to implement a JIT compiler for your interpreted language: you generate the machine code directly into memory (instead of to a file), then execute it.

      LLVM has many more developers than GCC, and is evolving and improving more quickly than GCC can. This is because of the licence: it turns out that corporations like Apple are more willing to provide developer resources for this open source project if the licence isn't copyleft. For this particular project, this means that the BSD license is more successful than the GPL. Of course, there are other projects for which the GPL produces better results in the real world.

      If you want to make a GPL fork of LLVM just for the pure pleasure of fucking over the original project due their heresy in choosing a license you don't approve of, well, good luck with that.

      --
      I have written a truly remarkable program which this sig is too small to contain.
    2. Re:License by phantomfive · · Score: 4, Interesting

      This is because of the licence: it turns out that corporations like Apple are more willing to provide developer resources for this open source project if the licence isn't copyleft.

      That's not really true, Apple contributed to GCC for years before LLVM. The problem was that Apple wanted features, and GCC wouldn't allow those features to be built. So finally Apple just gave up and built their own.

      This is the rule of running an open source project (and Linus does a really good job of it): give users what they want, or the users will leave.

      --
      "First they came for the slanderers and i said nothing."
    3. Re:License by tlhIngan · · Score: 3, Informative

      This is because of the licence: it turns out that corporations like Apple are more willing to provide developer resources for this open source project if the licence isn't copyleft.

      That's not really true, Apple contributed to GCC for years before LLVM. The problem was that Apple wanted features, and GCC wouldn't allow those features to be built. So finally Apple just gave up and built their own.

      This is the rule of running an open source project (and Linus does a really good job of it): give users what they want, or the users will leave.

      True, but Apple could also see the writing on the wall with the GPLv3 and what that could mean to their use of the compiler. Which is also why they poured a lot of effort into LLVM and wrote clang. This effort dated way back too - the earliest versions of OS X that started coming out with LLVM as an option was around the 10.4 era.

      A lot of companies saw what the GPLv3 was bringing to the table, and they didn't like it, so they moved on. Some, like Apple, realized they could stick around and fight with GCC and GPLv3, or work on an alternative.

      GCC is deliberately obtuse as well - Apple wanted a nice front end to help parse and recompile code in real time, and GCC is intentionally twisty to prevent that (and if you want to write a parser for code, why not reuse what the compiler actually uses?). LLVM is more modular and makes it easier to integrate with an IDE

      And in the end, I think having the diversity we do in compilers is refreshing - even if you hate LLVM with a passion, at least it's also brought forth development on GCC, which seems to have a history of stalling in development before someone else decides to fork it, revamp things, and have the fork become the official GCC.

      FYI - the very last checkin to GCC by Apple was related to Grand Central Dispatch to the Obj-C compiler - basically about blocks.

  7. Mixed backend languages is recipe for subtle bugs by Ungrounded+Lightning · · Score: 2

    From up-close-and-personal experience with Objective C and C++ (also Smalltalk), these languages have substantially different semantics regarding class identity (primarily: what version of overridden member functions you get) during construction and destruction. I wouldn't be surprised if Objectivce-C++ had yet another semantics, pulling "features" from both, and I have no clue about LVMM.)

    Building a frontend to compile to them, interchangeably, is a recipe for subtle bugs, if the frontend doesn't deal with these issues. Efficiency may go out the window if the frontend tries to impose one language's construction/destruction semantics on another. Doing so also brings up the issue of which semantics the compiler exposes to the programmer - each has its good and bad points, and each enables different - and incompatible - useful programming features.

    I'd be interested in what (if anything) Clang has done about this issue. (Unfortunately, I'm busy on other stuff, so I'll have to depend on others to elucidate this.)

    --
    Bantam Dominique roosters crow a four-note song. Once you've heard it as "Happy BIRTHday" you can't NOT hear it that way
  8. Re:Intermediate formats by dmoen · · Score: 2

    Clang can compile to the LLVM "IR" format, which is a mostly machine-independent Intermediate Representation. Kind of like bytecode.

    The IR file format has two variations: a human readable text format, and a more compact binary format.

    Given an IR file, you can optimize it, which produces another IR file, or you can compile it into an object file.

    --
    I have written a truly remarkable program which this sig is too small to contain.
  9. Evidence? by mveloso · · Score: 3, Interesting

    I would think that if these subtle bugs exist they'd be caught by the test suites. Do you have any actual evidence of these subtle bugs?

  10. G++ versus Clang++ by ShakaUVM · · Score: 4, Informative

    >better error messages, warnings, and static analysis from Clang. Those save me way more time than the speed of the compiler.

    This is the truth. Ain't nobody got time to read through a hundred lines of error messages to track down a single bug.

    As a simple test, I wrote the following code which has a simple mistake (using an integer instead of an int array in a range-based for loop):

    test.cc:

    #include
    int main() {
            int x = 0;
            for (int i: x) std::cout constexpr const _Tp* std::end(std::initializer_list)
              end(initializer_list __ils) noexcept"

    2 lines for a single straightforward error in clang++ 3.7 (with colors even!):

    "test2.cc:5:12: error: invalid range expression of type 'int'; no viable 'begin' function available
                    for (int i: x) std::cout i;"

    I currently use g++ with new programmers, and will be switching soon to clang++.

    Plus Clang does cool things like interoperate with things like YouCompleteMe to do real time compiling and error message generation for syntax completion in VIM.

    1. Re:G++ versus Clang++ by ShakaUVM · · Score: 2

      (Sigh, Slashdot. Stop eating code snippets in Plain Old Text mode. This is a place for geeks.)

      Here's the code that generated the bug, without Slashcode mangling it:

      int x;
      for (int i: x) std::cout i;

      109 lines of error messages in g++, 2 lines in clang++

    2. Re:G++ versus Clang++ by serviscope_minor · · Score: 2

      If you're marvelling over clang producing coloured error messages, then you're using an old version of gcc. Try switching to something in the new gcc-5 series. Contrary to popular belief, it's quite slow, but not hard to compile. Also, many distros have gcc-5 packages available.

      PS, both versions of your code got mangled, so I can't see what you're referring to precisely.

      --
      SJW n. One who posts facts.
  11. Re:Mixed backend languages is recipe for subtle bu by windwalkr · · Score: 2

    From up-close-and-personal experience with Objective C and C++ (also Smalltalk), these languages have substantially different semantics regarding class identity (primarily: what version of overridden member functions you get) during construction and destruction. I wouldn't be surprised if Objectivce-C++ had yet another semantics, pulling "features" from both, and I have no clue about LVMM.)

    Objective-C++ mixes the syntax of the two languages, and allows you to use either a C++ object or an Objective-C object at will, however it does not make C++ objects into Objective-C objects or vice versa. Any semantics relating to C++ objects still applies to C++ objects, and no additional semantics are implied.

    In short: things work as you'd expect, and there are no hidden gotchas.

    The only real complexities are what happens when you embed a C++ object as a member inside an Objective-C object (this doesn't change the semantics of the C++ object itself, but obviously may change the point at which the whole thing is destroyed) and what happens when you reference an Objective-C object from within a C++ object (some of the automatic refcounting syntactic sugar goes away and you have to actually understand what you're doing.) These don't introduce difficulties for the compiler, but could potentially be confusing for the programmer.

    I'm sure clang has its fair share of bugs, and I'm sure that GCC does also, that's just the nature of any complex codebase. The shared backend isn't really a contributing factor, any more so than them both emitting x86 machine code is a contributing factor.

  12. just a warning by Gravis+Zero · · Score: 2

    while clang is probably fine for most projects, if your project needs -std=c++14 then you should be warned that sometimes Clang can't properly deduce (even when you are explicit) variadic template parameters.

    for example, this code will not compile on Clang no matter what but works fine with G++.

    template<typename... ArgTypes> using deeper = void(*)(ArgTypes...);
    template<typename... ArgTypes> void shallow(deeper<ArgTypes...> arg) { }

    int main(int argc, char* argv[])
    {
        deeper<int> arg;
        shallow<int>(arg);
        return 0;
    }

    --
    Anons need not reply. Questions end with a question mark.
  13. Re:Developing in C/C++ by serviscope_minor · · Score: 2

    My current project uses a Blackfin DSP processor by Analog Devices. The toolset that Analog provides supports only C, C++, and assembly. I don't expect them to provide Java, .Net, PHP, Haskell, Python or [your favorite language here] anytime soon.

    You can run Linux on a blackfin. I'd strongly expect you could easily run Python or PHP on it. Not sure why you'd want to.

    --
    SJW n. One who posts facts.