Is C faster than C++ |

September 19th, 2005, 12:25 AM
| | | |
In one of my interview, some people asked me why C is faster C++, and tell
me to illustrate at least two reasons.
I can't find the answer in the web.
I'll appreciate any suggestion on this.
Thank you. | 
October 2nd, 2005, 07:15 PM
| | | | re: Is C faster than C++
On Sun, 2 Oct 2005 13:47:10 -0400, "P.J. Plauger" <pjp@dinkumware.com> wrote:
[color=blue]
>The fundamental issue is whether programming in C++ yields
>programs that are larger and slower than comparable programs
>written in C. In my extensive experience, the simple answer
>is yes. The most prudent course for a project manager is to
>assume 5 to 15 per cent overheads, and take for granted that
>the benefits of C++ will justify the extra costs. I went
>through a similar period with C a few decades ago, selling
>it against assembly language. I agree the overheads can be
>managed, often significantly reduced; and it's worth teaching
>people how to do so. But pretending that the problem doesn't
>exist at all does not help our credibility with a rightly
>critical audience of potential new users.[/color]
Now this I can agree with. Let's leave it at that, shall we?
-dr | 
October 3rd, 2005, 04:55 PM
| | | | re: Is C faster than C++
Dave Rahardja wrote:[color=blue]
> On Fri, 30 Sep 2005 17:49:09 +0200, "Branimir Maksimovic" <bmaxa@eunet.yu>
> wrote:
>[color=green][color=darkred]
> >>> If
> >>> exception
> >>> handling is not required, we can properly declare non-throwing functions
> >>> with
> >>> the throw() specification, or resort to compiler switches. I also imagine
> >>> that
> >>> a C++ compiler can assume that C functions declared extern "C" do not
> >>> throw.
> >>>
> >>
> >> throw() wouldn't help.
> >> To quote part of 15.5.1:
> >> "An implementation is not permitted to finish stack unwinding prematurely
> >> based on a determination that the unwind process will eventually cause
> >> a call to terminate()."[/color][/color]
>
> [snip]
>[color=green]
> >I've just investigated further. Exception specification makes run time
> >overhead to function
> >only if function throws or calls function that does not have throw()
> >specification.[/color]
>
> This has also been my experience. The overhead of non-throwing functions is
> exactly ZERO, both in run time code and in data space.
>[/color]
........[color=blue]
> With that quick exercise it is easy to see that exception handling overhead is
> exactly _zero_ with MSVC++ .NET when functions are properly declared throw().
> Furthermore, MSVC is smart enough to figure out that extern "C" functions do
> not throw.
>
>
> My experience with the embedded compiler that I use daily has been the same:
> the exception handling overhead for properly-declared code is not only
> trivial, it is _zero_.
>
> However, I will admit again that the decision to assume that functions with no
> throw clause can "throw anything" instead of "throw nothing" makes it very
> difficult for compilers to automatically elide the generation of exception
> handling infrastructure. Declaring functions throw() when it really doesn't
> throw anything is good practice whenever resources are at a premium.
>
>[/color]
Yes, throw() specification seems to be the best practice, because
it completely eliminates exception code and data both on linux and
windows with gcc, too. Without them even C compiled as C++ has overhead
on linux. One thing more , for gcc extern "C" functions have to be
declared throw() as well. On windows && gcc,every function that have
destructor(s) (and there are almost no C++ programs that doesn't have
auto objects in functions)executed has big run time overhead
(entry/exit exception code added).
So, mister P.J.Plauger is generaly right, we have to put lot's of
throw()
specifications in order to avoid either code bloat(linux) or run time
penalty
and code bloat(windows), even with same compiler on different
platforms.
Greetings, Bane. | 
October 3rd, 2005, 11:15 PM
| | | | re: Is C faster than C++
Branimir Maksimovic wrote:[color=blue]
> Dave Rahardja wrote:[color=green]
> > On Fri, 30 Sep 2005 17:49:09 +0200, "Branimir Maksimovic" <bmaxa@eunet.yu>
> > wrote:
> >[color=darkred]
> > >>> If
> > >>> exception
> > >>> handling is not required, we can properly declare non-throwing functions
> > >>> with
> > >>> the throw() specification, or resort to compiler switches. I also imagine
> > >>> that
> > >>> a C++ compiler can assume that C functions declared extern "C" do not
> > >>> throw.
> > >>>
> > >>
> > >> throw() wouldn't help.
> > >> To quote part of 15.5.1:
> > >> "An implementation is not permitted to finish stack unwinding prematurely
> > >> based on a determination that the unwind process will eventually cause
> > >> a call to terminate()."[/color]
> >
> > [snip]
> >[color=darkred]
> > >I've just investigated further. Exception specification makes run time
> > >overhead to function
> > >only if function throws or calls function that does not have throw()
> > >specification.[/color]
> >
> > This has also been my experience. The overhead of non-throwing functions is
> > exactly ZERO, both in run time code and in data space.
> >[/color]
> .......[color=green]
> > With that quick exercise it is easy to see that exception handling overhead is
> > exactly _zero_ with MSVC++ .NET when functions are properly declared throw().
> > Furthermore, MSVC is smart enough to figure out that extern "C" functions do
> > not throw.
> >
> >
> > My experience with the embedded compiler that I use daily has been the same:
> > the exception handling overhead for properly-declared code is not only
> > trivial, it is _zero_.
> >
> > However, I will admit again that the decision to assume that functions with no
> > throw clause can "throw anything" instead of "throw nothing" makes it very
> > difficult for compilers to automatically elide the generation of exception
> > handling infrastructure. Declaring functions throw() when it really doesn't
> > throw anything is good practice whenever resources are at a premium.
> >
> >[/color]
>
> Yes, throw() specification seems to be the best practice, because
> it completely eliminates exception code and data both on linux and
> windows with gcc, too. Without them even C compiled as C++ has overhead
> on linux. One thing more , for gcc extern "C" functions have to be
> declared throw() as well. On windows && gcc,every function that have
> destructor(s) (and there are almost no C++ programs that doesn't have
> auto objects in functions)executed has big run time overhead
> (entry/exit exception code added).
> So, mister P.J.Plauger is generaly right, we have to put lot's of
> throw()
> specifications in order to avoid either code bloat(linux) or run time
> penalty
> and code bloat(windows), even with same compiler on different
> platforms.
>
> Greetings, Bane.[/color]
There are some compilers that have "zero runtime overhead" exception
handling; but the tradeoff they make is in size. Exception support can
add significantly to the size of compiled code.
I don't see how a throw() specification would be likely to eliminate
any exception processing overhead. After all, a throw() specification
is no guarantee that the function will not throw an exception. It only
guarantees that a caller will never be able to catch an exception
thrown during a call to that routine [because the program will have
stopped running]. And in order to provide this guarantee the compiler
must add exception processing logic to a function with a throw()
specification just to make sure that no thrown exceptions are allowed
to escape.
In short, to eliminate exception overhead really requires going outside
the syntax defined by the language and to use use a pragma or an other
compiler-dependent way to disable the feature.
Greg | 
October 4th, 2005, 12:55 AM
| | | | re: Is C faster than C++
Greg wrote:[color=blue]
> Branimir Maksimovic wrote:[color=green]
> > Dave Rahardja wrote:[color=darkred]
> > > On Fri, 30 Sep 2005 17:49:09 +0200, "Branimir Maksimovic" <bmaxa@eunet.yu>
> > > wrote:
> > >
> > > >>> If
> > > >>> exception
> > > >>> handling is not required, we can properly declare non-throwing functions
> > > >>> with
> > > >>> the throw() specification, or resort to compiler switches. I also imagine
> > > >>> that
> > > >>> a C++ compiler can assume that C functions declared extern "C" do not
> > > >>> throw.
> > > >>>
> > > >>
> > > >> throw() wouldn't help.
> > > >> To quote part of 15.5.1:
> > > >> "An implementation is not permitted to finish stack unwinding prematurely
> > > >> based on a determination that the unwind process will eventually cause
> > > >> a call to terminate()."
> > >
> > > [snip]
> > >
> > > >I've just investigated further. Exception specification makes run time
> > > >overhead to function
> > > >only if function throws or calls function that does not have throw()
> > > >specification.
> > >
> > > This has also been my experience. The overhead of non-throwing functions is
> > > exactly ZERO, both in run time code and in data space.
> > >[/color]
> > .......[color=darkred]
> > > With that quick exercise it is easy to see that exception handling overhead is
> > > exactly _zero_ with MSVC++ .NET when functions are properly declared throw().
> > > Furthermore, MSVC is smart enough to figure out that extern "C" functions do
> > > not throw.
> > >
> > >
> > > My experience with the embedded compiler that I use daily has been the same:
> > > the exception handling overhead for properly-declared code is not only
> > > trivial, it is _zero_.
> > >
> > > However, I will admit again that the decision to assume that functions with no
> > > throw clause can "throw anything" instead of "throw nothing" makes it very
> > > difficult for compilers to automatically elide the generation of exception
> > > handling infrastructure. Declaring functions throw() when it really doesn't
> > > throw anything is good practice whenever resources are at a premium.
> > >
> > >[/color]
> >
> > Yes, throw() specification seems to be the best practice, because
> > it completely eliminates exception code and data both on linux and
> > windows with gcc, too. Without them even C compiled as C++ has overhead
> > on linux. One thing more , for gcc extern "C" functions have to be
> > declared throw() as well. On windows && gcc,every function that have
> > destructor(s) (and there are almost no C++ programs that doesn't have
> > auto objects in functions)executed has big run time overhead
> > (entry/exit exception code added).
> > So, mister P.J.Plauger is generaly right, we have to put lot's of
> > throw()
> > specifications in order to avoid either code bloat(linux) or run time
> > penalty
> > and code bloat(windows), even with same compiler on different
> > platforms.
> >
> > Greetings, Bane.[/color]
>
> There are some compilers that have "zero runtime overhead" exception
> handling; but the tradeoff they make is in size. Exception support can
> add significantly to the size of compiled code.
>
> I don't see how a throw() specification would be likely to eliminate
> any exception processing overhead. After all, a throw() specification
> is no guarantee that the function will not throw an exception. It only
> guarantees that a caller will never be able to catch an exception
> thrown during a call to that routine [because the program will have
> stopped running].[/color]
Well if you look at my previous post that is what I thought about
throw().
But, it simply elliminates any trace of exception handling code and
data in gcc object files. I guess compiler knows that
eh code is not needed if every single function used in compilation unit
(declared or defined) has throw() specification.
And in order to provide this guarantee the compiler[color=blue]
> must add exception processing logic to a function with a throw()
> specification just to make sure that no thrown exceptions are allowed
> to escape.[/color]
I looked at generated assembly and this is not the case.
If function has throw() specification (with or without auto objects
with destructors)and does not calls something that
can throw (it is good practice that destructors have throw()
anyway) no eh code or data is generated for that function.
It seems that that is the case with VC too (according to Dave).
So, finally this thread gaved me a good knowledge about exception
specs, and when they should be used - in functions that actually
don't throw exceptions :)
I was rather carelless about specs, but now, I know that compilers
can optimise unnedded eh code and data out when they see them.
They won't heart anyway.
Greetings, Bane. | 
October 4th, 2005, 04:55 AM
| | | | re: Is C faster than C++
On 3 Oct 2005 15:03:55 -0700, "Greg" <greghe@pacbell.net> wrote:
[color=blue]
>There are some compilers that have "zero runtime overhead" exception
>handling; but the tradeoff they make is in size. Exception support can
>add significantly to the size of compiled code.[/color]
Yes, I've seen at least one implementation that uses a static table of "throw
ranges" or "call sites" to deduce the objects that need to be destructed if an
exception were to be thrown at that point. Such implementations have literally
zero execution overhead (using no additional stack space and no additional
instructions in the stream). When exceptions are thrown control is passed to a
global exception handler, along with the current exception-thrower's address
and stack pointer and does the unwinding based on the tables.
The cost is obviously the substantial tables that need to be linked in
(although in most OS implementations this can be done so that the tables do
not get paged into physical memory until an exception actually occurs).
[color=blue]
>I don't see how a throw() specification would be likely to eliminate
>any exception processing overhead. After all, a throw() specification
>is no guarantee that the function will not throw an exception.[/color]
Actually it does (see 15.4.11), or at least /should/. However, the throw()
specification does not become part of the function type, so a function
declared throw() in one module looks identical to the linker as the function
defined without the throw-specification.
MSVC at least does give a compile-time warning if you declare a function
throw() and then proceed to throw an exception in it.
I guess the secret is to use the same declaration (i.e. header file) for the
declaration of a function everywhere in the program.
[color=blue]
>In short, to eliminate exception overhead really requires going outside
>the syntax defined by the language and to use use a pragma or an other
>compiler-dependent way to disable the feature.[/color]
To completely eradicate exception handling overhead once and for all you
probably need to use a compiler switch. I wonder what this does to library
functions that are specified to throw exceptions though, such as operator
new().
-dr |  | | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 225,689 network members.
|