GCC, Clang, and MSVC compilers with C++

Rescue Network

If your own compiler does not yet support the C++ standard you need, the web might provide a solution. The web is home to a wide range of online compilers for C++ that use one of the three major compilers in the background. Arne Mertz offers an excellent overview of online compilers [10]. This article explores a few of the most common options.

The Wandbox compiler [11] supports an impressive variety of GCC and Clang versions. The Online Visual C++ compiler [12] is used for Windows. More impressive is the Explorer compiler [13] by Matt Godbolt, which generates assembler code for a variety of compilers.

The online C++ compiler Coliru [14] has a unique selling point: You can integrate it into any website. For example, the online C++ reference at cppreference.com uses it [15].

Online compilers have the following benefits:

  • They let you test new features of the C++ standard. For example, you can test whether a compiler upgrade makes sense.
  • Difficult to understand error messages suddenly make sense when another compiler compiles the code. Clang stands out above all with its understandable error messaging.
  • Code is easier to verify. Undefined behavior in the source code has different effects. The program provides the wrong or supposedly correct result. Undefined behavior also means that source code cannot be compiled or the program crashes at run time.

Testing your code online with different compilers and compiler versions will verify its correctness simply but effectively.

An example is shown in Listing 2. This code leads to undefined behavior. Since C++11, C++ has supported the delegation of constructors. This should not create a recursion, but it does in the example. The constructor for char calls the constructor for double, which in turn calls the constructor for char… and so on.

Listing 2

Recursive Calling of Constructors

 

How do the Wandbox front end (Clang, GCC) and the Visual C++ Online Compiler (MSVC) deal with recursion? Whereas GCC exits with a segmentation fault at run time (Figure 3), the MSVC executable goes into an endless loop that is abruptly interrupted by the compiler front end. Only Clang is really trustworthy (Figure 4). The Clang compiler notices at build time that a recursion appears in the program.

Figure 3: GCC throws a segfault due to the recursive delegation of constructors.
Figure 4: When compiling the program, Clang notices that there is a recursion.

Finally, the previously mentioned Explorer compiler takes over the job. Explorer generates the assembly instructions for an impressive number of compilers and compiler versions, supporting GCC, Clang, MSVC, and many others. These instructions are shown in the graphical front end side by side with the source code. To make it easier to map the two, Explorer color highlights the source code lines and the corresponding assembler instructions. The effect is enhanced even more with the cursor placed in the source code so that Explorer highlights the corresponding assembler instructions (Figure 5).

Figure 5: The Explorer compiler highlights source code and associated assembly instructions in color.

Explorer's focus on assembly instructions has a number of benefits:

  • By comparing the source code with the corresponding assembly instructions, you get a deeper insight into the compilation and optimization process.
  • You can discover whether the compiler calculates an expression at compilation time or calls a function inline.
  • It becomes clear how the various optimization levels affect the assembly instructions.

The last point is perhaps the biggest added value of the Explorer compiler. Thanks to Explorer, it is possible to understand the often-not-completely-intuitive behavior of the optimizer with a little practice. Consider the example shown in Listing 3.

Listing 3

Singleton Pattern

 

Listing 3 uses the singleton pattern (lines 6 to 18). The big question is how much time it takes to call the singleton 10 million times (line 24). The elapsed time is given in line 28. With GCC, the program is quickly compiled without and with maximum optimization (-O3). Figure 6 provides figures for performance.

Figure 6: The execution time of the singleton calls in seconds.

Surprised? There is every reason to be, because the maximum optimized execution happens far too fast – unless the Optimizer was playing a trick. A look at the Explorer compiler sheds some light on the outcome. Figure 7 shows the source code in the non-optimized variant, and Figure 8 shows the corresponding assembly instructions. Nothing suspicious so far.

Figure 7: Source code in non-optimized version.
Figure 8: Assembler instructions for the non-optimized variant.

Figure 9 is much more suspicious. The singleton call MySingleton::getInstance(); is not highlighted, which can only mean that there are no appropriate assembly instructions. See Figure 10 – not only are the instructions missing for the singleton call, but they are also missing for the for-loop. How is that possible? Since running the for-loop has no effect, the optimizer can remove it, which it does, but this leads to an absurd measurement of performance.

Figure 9: Source code of the optimized version.
Figure 10: Optimized variant assembler instructions.

Know Your Compiler!

The online compilers offer unbeatable help when it comes to keeping up with the three-year cycle of modern C++ standards, which means that contemporary C++ developers don't have to ask whether they are using the best of all C++ compilers.

In the end, each compiler shows strengths and weaknesses. GCC and Clang implement the C++ core language faster than MSVC. However, MSVC often has the edge when it comes to implementing the C++ library. How can you harness the functional diversity of all three of the big three compilers? With the help of the excellent online compilers.

Infos

  1. GCC: https://gcc.gnu.org
  2. Clang: https://clang.llvm.org
  3. MSVC: https://docs.microsoft.com/en-us/cpp/
  4. GNU ARM Toolchain: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm
  5. An overview of the C++17 standard, its features, and compiler support: http://en.cppreference.com/w/cpp/compiler_support
  6. A parallel STL implements HPX: http://stellar.cct.lsu.edu/projects/hpx/
  7. The Sanitizer checks the use of addresses, memory, and threads: https://github.com/google/sanitizers/wiki
  8. Windows port of sanitizer: https://github.com/google/sanitizers/wiki/AddressSanitizerWindowsPort
  9. Thread Sanitizer: https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual
  10. Arne Mertz's collection of C++ online compilers: https://arnemertz.github.io/online-compilers/
  11. Wandbox online compiler: https://wandbox.org
  12. Online Visual C++ compiler: http://webcompiler.cloudapp.net
  13. Explorer compiler: https://godbolt.org
  14. Coliru: http://coliru.stacked-crooked.com
  15. Online C++ reference: http://en.cppreference.com/w/

The Author

Rainer Grimm is a trainer, a seminar lecturer on modern C++ and Python, and a published author, including C++, C++11 f¸r Programmierer, and C++-Standardbibliothek (O'Reilly), as well as The C++ Standard Library and Concurrency with Modern C++ (Leanpub).

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Crystal

    Crystal is an open source project that seeks to combine the best of two worlds: the simplicity of a language syntax similar to Ruby and the speed and capabilities of the LLVM platform.

  • Kernel News

    In kernel news: Rust in Linux; and Compiler and Kernel Frenemies.

  • Intel Updates C++ and Fortran Compilers for Linux

    Chipmaker Intel has reworked its proprietary Linux compilers. The Intel C/C++ compiler version 11.0 now supports the mobile processor Atom. The same version of the Fortran compiler now supports the Fortran 2003 language standard.

  • Kernel News

    This month in Kernel News: Shared Processes with Hyper-Threading; Cleaning Up printk(); and Rust in the Kernel.

  • Kernel News

    This month in Kernel News: Dealing with Older GCC Versions; and On-boarding New Kernel Hackers.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News