4

I've seen a lot of arguments over the general performance of C code compiled with a C++ compiler -- I'm curious as to whether there are any solid experimental studies buried beneath all the anecdotal flame wars you find in web searches. I'm particularly interested in the GCC suite, but any data points would be interesting. (Comparing the assembly of "Hello, World!" is not as robust as I'd like. :-)

I'm generally assuming you use the "embedded style" flags -- no exceptions or RTTI. I also wouldn't mind knowing if there are studies on the compilation time itself. TIA!

cdleary
  • 69,512
  • 53
  • 163
  • 191
  • Comparing different compilers? Comparing C compilation vs. C++ compilation by the same compiler? (would there be a difference?) And what are "embedded style" flags? – Michael Burr Aug 14 '09 at 06:08
  • By the same compiler suite (i.e. gcc vs. g++). Because of specification differences, useful optimizations may be more or less applicable in one language's intermediary representation versus the other (or some optimizations may be enabled for one language that are not enabled for another). I mentioned two embedded style flags -- those that disable exception support and those that disable RTTI. – cdleary Aug 14 '09 at 06:13
  • If you compile C-like code, I don't see how either of those flags is applicable anyway - if you only have PODs, there are no destructors anywhere, and thus no need for exception handling code. Since there are no virtual functions, there's no need for RTTI, except for compile-time-resolved `typeid` calls - and if there are none of those, then no need whatsoever. – Pavel Minaev Aug 14 '09 at 06:30
  • @Pavel: Perhaps, I just figured cutting out components of the language runtime can only benefit performance if they're unused. – cdleary Aug 14 '09 at 06:45
  • The C++ principle is that you don't pay for what you don't use. In this case, though, assuming that's true is kind of begging the question, which is in effect "if I only use C, does using a C++ compiler cost extra?" – Steve Jessop Aug 14 '09 at 10:42
  • which language runtime components would be cut? The point is that there is no overhead in *C++* if you don't use those features. So if you don't use them in C, there is nothing more to cut. – jalf Aug 14 '09 at 11:23
  • 1
    The more I think about this, the more I think it's an interesting question. Not that I have an answer (or even know how someone would effectively test it). The idea of C++ is that you don't pay for what you don't use - my interpretation of the question is, how well do compilers actually attain this ideal? I'd guess they do pretty well, but that's not the same as actually measuring. – Michael Burr Aug 14 '09 at 17:06
  • @onebyone: It would be begging the question if I were actually making the assumption that the statement is correct. I am asking for real-world experimental evidence that demonstrates that conclusion. – cdleary Aug 14 '09 at 23:22
  • It should be pretty easy to prove the argument in either direction. Which helps fuel the flames. You cannot nail down a single benchmark or even a suite that really covers all of the real world so you cannot conclusively decide either way. You have to test each program of interest to you with each compiler of interest to find what the fastest one today. And tomorrows patches will change the results. – old_timer Aug 18 '09 at 13:33
  • @dwelch: I'd be happy to see evidence either (both) ways, as that would at least demonstrate something. Right now I can't find anything but speculation and anecdotes. :-) – cdleary Aug 19 '09 at 00:03

7 Answers7

13

Adding a datapoint (or at least an anecdote):

We were recently writing a math library for a small embedded-like target, and started writing it in C. About halfway through the project, we switched some of the files to C++, largely in order to use templates for some of the functions where we'd otherwise be writing many nearly-identical pieces of code (or else embedding 40-line functions in preprocessor macros).

At the point where we started switching over, we had a very careful look at the generated assembly code (using GCC) on a number of the functions, and confirmed that it was in fact essentially identical whether the file was compiled as C or C++ -- where by "essentially identical" I mean the differences were in things like symbol names and the stuff at the beginning and end of the assembly file; the actual instructions in the middle of the functions were exactly identical.

Sorry that I don't have a more solid answer.

Edit to add, 2013-03-24: Recently I came across an article where Rusty Russell compared performance on GCC compiled with a C compiler and compiled with a C++ compiler, in response to the recent switch to compiling GCC as C++: http://rusty.ozlabs.org/?p=330. The conclusions are interesting: The version compiled with a C++ compiler was very slightly slower; the difference was about 0.3%. However, that was entirely explained by load time differences caused by larger debug info; when he stripped the binaries and removed the debug info, the differences were less than 0.1% -- i.e., essentially indistinguishable from measurement noise.

Brooks Moses
  • 9,267
  • 2
  • 33
  • 57
1

I don't know of any studies off-hand, but given the C++ philosophy that you don't pay the price for features you don't use, I doubt there'd be any significant difference between compiling C code with the C compiler and with the C++ compiler.

Mark Bessey
  • 19,598
  • 4
  • 47
  • 69
  • Right, that's what most of the people say in the flame war; however, there's also anecdotal evidence on lkml that the Linux kernel attempted a compilation with g++ some time back and wound up with a significant slowdown. – cdleary Aug 14 '09 at 06:39
  • Compiling the Linux kernel is a special case; they have restrictions such as stack size and heap allocation which don't apply to normal applications. – MarkR Aug 14 '09 at 07:04
  • On Linux kernel in C++: it wasn't just the slowdown. There were difficulties managing memory and the whole exception handling in the kernel is a nightmare to manage across contexts. Torvalds mentions those in a mail about it back in 2004. I don't know how much of this has changed since then. – Michael Foukarakis Aug 14 '09 at 07:19
  • I doubt they added exceptions just for the recompile. I was under the impression it was as-is. In any case, this is still anecdotal, and my question is all about the hard evidence! – cdleary Aug 14 '09 at 07:33
  • I understand GCC is at least somewhat optimized to build Linux kernels, but those optimizations will not magically carry over to g++. – MSalters Aug 14 '09 at 08:27
  • 3
    To be fair, the Linux Kernel Mailing List FAQ seems to indicate that the experiment of compiling the Linux kernel with g++ was performed in 1992. I think it's safe to assume that those results tell you nothing about what to expect now, given 17 years of GCC development in the mean time. – Mark Bessey Aug 14 '09 at 21:19
  • I'll readily invalidate an anecdote with speculation. In the end, I'm really just hoping for some actual data -- you know, science! It works! – cdleary Aug 14 '09 at 23:12
  • 1
    Last time I read Linus' rant about C++, it mentionned a try in the nineties, and how it was crappy, and how C++ design was worth nothing. I was under the impression his problem with C++ was more getting out of the "C subset" of C++ than anything else, that he saw no interest in classes, destructor, object design, etc. etc.. But again, it was a rant, somewhat like the FQA site, without real knowledge of the language, and without specifics about real performance issue tied to compiler performance. – paercebal Aug 15 '09 at 08:07
  • 1
    For example, this link: http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918 . You'll see no benchmark, nor even discussion about the generated machine code. Only about philosophy or design. This one: http://linuxgazette.net/issue32/rubini.html seems more thoughful... Again, no raw performance issue, only language difficulty and compile time – paercebal Aug 15 '09 at 08:26
1

I don't know of any studies and I doubt that anyone will spend the time to do them. Basically, when compiling with a C++ compiler, the code has the same semantic as when compiling with a C compiler, so it's down to optimization and code generation. But IMO these are much too much compiler-specifc in order to allow any general statements about C vs. C++.

What you mainly gain when you compile C code with a C++ compiler is a much stricter checking (function declarations etc.). IMO this would make compiling C code with a C++ compiler quite attractive. But note that, if you have a large C code base that's never run through a C++ compiler, you're likely facing a very steep up-hill battle until the code compiles clean enough to be able to see any meaningful warnings.

sbi
  • 219,715
  • 46
  • 258
  • 445
  • Why would using a C++ compiler result in stricter checking? Or are you one of these people who seem to never have heard of warning flags (at least `-pedantic -Wall -Wextra` for gcc; for a more complete list, see here: http://stackoverflow.com/questions/432835/how-do-you-ensure-that-you-as-programmer-have-written-quality-c-code/432852#432852 )? – Christoph Aug 14 '09 at 09:43
  • @Christoph: C++ _as a language_ is stricter. For example, it doesn't allow implicit conversions from ´void*` to any other pointer type -- you have to cast explicitly. Things like this are what I was referring to. – sbi Aug 14 '09 at 09:50
  • C++ might be a safer language, but you want to use a C++ compiler to *compile C code*! The (non-)issue of implicit cast of `void *` aside, there isn't much gain of C++-compatible C over C99 - actually, it would be a regression as C++ doesn't support things like compound literals or designated initializers; the only real problem I can think of a C++ compiler can solve is the silent dropping of `const` via the return value of (library) functions, but then you'd have to use the overloaded C++ version of the stdlib - which would result in code which can't be compiled with a C compiler any longer – Christoph Aug 14 '09 at 10:23
  • If we're talking of C being compilable by a C++ compiler, we're talking of C89. C99 is not an option for this, so I wasn't even considering it. With this issue out of the way, we're back to the diagnostics. And here it's a question which camp you're in. In the C++ camp `void*` is generally frowned upon, since casting from `void*` is inherently unsafe -- hence compilers requiring you to do that explicitly. If you're in the C camp -- fine. Then just don't use a C++ compilers. If you like C++, but are stuck with a C code base, you might like to compile it with a C++ compiler. – sbi Aug 14 '09 at 19:51
  • @sbi: The "stricter checking" statement is irrelevant to this question and largely troll bait. I'm asking specifically about perf and evidence. – cdleary Aug 14 '09 at 23:17
  • @cdleary: And I answered that. To say it more directly: I'd expect the same source code to compile to the same binary code using the same compile -- regardless whether it's in C or C++ mode. And I expect that to be different for different compilers -- regardless whether in C or in C++ mode. – sbi Aug 14 '09 at 23:41
  • @sbi: Yes, I understand that many people would expect that result. The question asks for experimental evidence. It's all about the science! – cdleary Aug 15 '09 at 02:24
1

The GCC project is currently under a transition from C to C++ - that is, GCC may be implemented in C++ in the future, it is currently written in C. The next release of GCC will be written in the subset of C which is also valid C++.

Some performance tests were performed on g++ vs gcc, on GCC's codebase. They compared the "bootstrap" time, which means compiling gcc with the sysmem compiler, then compiling it with the resulting compiler, then repeating and checking the results are the same.

Summary: Using g++ was 20% slower. The compiler versions were slightly different, but it was thought that this wouldn't cause there 20% difference.

Note that this measures different programs, gcc vs g++, which although they mostly use the same code, have different front-ends.

Paul Biggar
  • 27,579
  • 21
  • 99
  • 152
0

I've not tried it from a performance standpoint, but I think compiling C applications with the C++ compiler is a good idea, as it will prevent you from doing "naughty" things such as using functions not declared.

However, the output won't be the same - at the very least, you'll get different symbols, which will render it (mostly) unlinkable with code from the C compiler.

So I think what you really mean is "Is it ok from a performance standpoint, to write C++ code which is very C-like and compile it with the C++ compiler" ?

You would also have to not be using some C99 things such as bool_t which C++ doesn't support on the grounds of having its own ones.

MarkR
  • 62,604
  • 14
  • 116
  • 151
  • I mean I have an existing body of C code and I'm willing to make small syntactic corrections to (like casting values out of malloc, getting rid of stdbool, and so on) in order to get it to compile with a C++ compiler and I'm interested in the performance delta. – cdleary Aug 14 '09 at 07:32
  • I'd have to say, "try it and see". I don't imagine that the binary would run any slower at runtime, it might be a bit bigger and have a longer startup time. – MarkR Aug 14 '09 at 07:44
  • Right, so my question is wondering if people "tried it and saw" a bunch of times (hopefully on various applications), recorded the results, and published them. ;-) – cdleary Aug 14 '09 at 07:51
  • cdleary - if you decide to "try it and see", I'd be interested if you posted a summary of the results on you blog. – Michael Burr Aug 15 '09 at 19:30
0

Don't do it if the code has not been designed for. The same valid language constructs can lead to different behavior if interpreted as C or as C++. You would potentially introduce very difficult to understand bugs. Less problematic but still a maintainability nightmare; some C constructs (especially from C99) are not valid in C++.

xilun
  • 631
  • 4
  • 2
-1

In the past I have done things like look at the size of the binary which for C++ was huge, that doesnt mean they simply linked in a bunch of unusued libraries. The easiest might be to use gcc -S myprog.cpp vs gcc -S myprog.c and diff the assembler output.

old_timer
  • 69,149
  • 8
  • 89
  • 168