Why We Use C Than C++...

R

Richard Heathfield

Walter Bright said:
It's perfectly reasonable to use C++ to pick and choose what features you
might want to use.

If you want to use C++-specific features, clearly you will need a C++
compiler. I don't think anyone is disputing that.
 
U

Ulrich Eckhardt

Logan said:
If restricting yourself to the C-like features
carries no performance penalty, doesn't it seem likely that at least a
few useful C++-only features have no performance penalty compared to
equivalent way of doing things in C?

For example, C++ allows you to do this:

int *i = new int[100];

There is no reason the performance of this should be any worse than
the C equivalent:

int *i = (int *) malloc (100 * sizeof (int));

Yes there is. operator new[] will throw an exception when it fails, so the
'equivalent' in C at least requires some error checking.

Also, let's not use bad programming habits as example, both your lines are
examples of bad code.

// C++
std::tr1::scoped_array<int> i(new int[size]);

// C
int* i = malloc( size * (sizeof (int)));
if(!i)
return ENOMEM;

Uli
 
U

Ulrich Eckhardt

Keith said:
C++'s namespace facility provides a cleaner way around this. For
example, an "xyz" library might put all its symbols in the "xyz"
namespace, giving symbol names like "xyz::create()". The difference
is that it's a feature built into the language, making it easier to
use and harder to avoid, and you can refer to the function as just
"create()" if you want to. (I don't use C++, so I could be missing
something.)

Almost. Normally, you can refer to a symbol in a namespace only explicitly
via 'xyz::symbol', not just with 'symbol'. However, you can manipulate the
current context a bit: 'using namespace xyz;' will make the compiler
search the whole namespace when looking for a symbol, 'using xyz::symbol;'
will only import that particular symbol into the current context.

When you write code that is in a namespace, that namespace is implicitly
added to the list of searched namespaces.

When you call a function, it is also looked for in the namespace(s) of its
argument(s).

You can nest namespaces, i.e. declare another namespace inside a namespace.

You can do aliasing like with typedef. E.g. a fictitious library 'webtools'
for web related stuff containing code in several namespaces:
namespace smtp = webtools::protocols::smtp;
smtp::query q; // refers to webtools::protocols::smtp::query

So much for a short overview of C++ namespaces.

Uli
 
M

Mark McIntyre

I'm not aware of any places where, compiling the same source code, it's
faster.

I am. The overhead however isn't inherent in C or C++, its to do with
the implementation and how libraries are loaded - some C++ compilers
I've met like an app to load all their libraries at startup, even if
you don't need all the functions in them...
Mark McIntyre
 
M

Mark McIntyre

That's a good point. But, C++ has about 14 billion extra features
beyond that which C has.

Possibly true, but irrelevant. Obviously, if you use those features,
the C++ app is likely to run slower than the "hello world" C app...
:)

Mark McIntyre
 
M

Mark McIntyre

Is it? No one's told me... how do you think vector gets its memory?

How the implementation does something is not relevant - it could use
black magic for all you care. Personally I strongly suspect that on
intel architectures, its calling the low level malloc function....

Enough of the stupid C vs C++ war. Both languages have their place.
This thread was probably started by a troll, lets just all killfile
it.
Mark McIntyre
 
W

Walter Roberson

Logan said:
If restricting yourself to the C-like features
carries no performance penalty, doesn't it seem likely that at least a
few useful C++-only features have no performance penalty compared to
equivalent way of doing things in C?
For example, C++ allows you to do this:
int *i = new int[100];
There is no reason the performance of this should be any worse than
the C equivalent:
int *i = (int *) malloc (100 * sizeof (int));
Yes there is. operator new[] will throw an exception when it fails, so the
'equivalent' in C at least requires some error checking.

I'm not sure if you are arguing for or against the proposition there ;-)

As you point out, new[] will throw exceptions -- and that means you
need the overhead of exception support, unless you are *sure*
you aren't going to catch the exception (which would require
a lot of intra-procedural analysis.) From what I've read, the
overheads of exception support are quite high.
 
W

Walter Roberson

Walter Bright said:
There is one case where using a C++ compiler for C code may increase
performance - C++ uses a different function calling convention than C, a
faster one. The reason C compilers don't adopt it is for binary
compatibility with C compilers that predate function prototypes. The
difference (callee cleans the stack, rather than the caller) can amount to 1
to 3%. (Yes, I've measured it <g>.)

Ah? Could you post the relevant section numbers of the C and C++
standards that mandate particular calling conventions? Or, for
that matter, the section number of the C standard that mandates
that a "stack" exist at all ?
 
I

Ian

Walter said:
Yes there is. operator new[] will throw an exception when it fails, so the
'equivalent' in C at least requires some error checking.


I'm not sure if you are arguing for or against the proposition there ;-)

As you point out, new[] will throw exceptions -- and that means you
need the overhead of exception support, unless you are *sure*
you aren't going to catch the exception (which would require
a lot of intra-procedural analysis.) From what I've read, the
overheads of exception support are quite high.

Don't forget we are talking about kernel programming. In this domain
you don't have the luxury of run time support, so you provide your own
new and delete operators. The signature may have an exception
specification, but you don't have to use it.

Ian
 
W

Walter Bright

Walter Roberson said:
Ah? Could you post the relevant section numbers of the C and C++
standards that mandate particular calling conventions? Or, for
that matter, the section number of the C standard that mandates
that a "stack" exist at all ?

We're talking about performance of using C vs C++ for a project. Nothing in
either standard mandates a word about performance, and nobody said they did.
However, in the real world for real CPUs and real compilers, that
implementation difference does exist for the reasons mentioned. The C++
standard does allow for a difference in calling convention with the extern
"C" construct.

There's a lot more to picking a language for a particular project than what
the standard says.

-Walter Bright
www.digitalmars.com C, C++, D programming language compilers
 
K

Keith Thompson

Ulrich Eckhardt said:
Almost. Normally, you can refer to a symbol in a namespace only explicitly
via 'xyz::symbol', not just with 'symbol'. However, you can manipulate the
current context a bit: 'using namespace xyz;' will make the compiler
search the whole namespace when looking for a symbol, 'using xyz::symbol;'
will only import that particular symbol into the current context.

Right, that's what I meant by "if you want to".

[...]
You can do aliasing like with typedef. E.g. a fictitious library 'webtools'
for web related stuff containing code in several namespaces:
namespace smtp = webtools::protocols::smtp;
smtp::query q; // refers to webtools::protocols::smtp::query

One more question. In C, if two libraries use the same identifier,
it's difficult or impossible for a program to use both libraries.
Using a library-specific prefix can avoid this, but if two libraries
use the same prefix you still have the same problem.

Suppose two C++ libraries use the same namespace identifier, say
"foo". Is it possible to use both libraries by aliasing one or both
of the namespaces? For example, could the program refer to one
namespace as "foo1" and the other as "foo2"?

Without such a feature, namespaces are useful, but all they really do
is encourage some structure in naming and allow abbreviations in some
cases; the don't give you anything you couldn't do in C with some
extra work. With such a feature, they would solve a problem that
can't really be solved in C, which could be an argument (here's where
it becomes marginally topical) for adding C++-style namespaces to a
future C standard.
 
L

Logan Shaw

Bjørn Augestad said:
Logan Shaw wrote:

No size overhead either?

Nope, no size overhead, because the equivalent thing is to implement
a set of functions twice, once for each type that must be dealt with.
Whether you do this manually in C or have the compiler do it for you
automatically in C++, it still results in two chunks of object code
that are very similar.

Granted, it's not all that often that you encounter a situation
where you need to do that, but it can happen, and C++ could make
your life easier in that case, without reducing the performance
or increasing the size of the executable.

I realize this is not a common problem, but my whole point here is
this: most people already agree that putting the same code through
a C and a C++ compiler will result in similar speeds in the output.
I am just trying to establish that it is possible to have similar
speed (and code size) when using some C++-only features. Once
that is established, there is no argument that using C++ leads to
bad performance; it becomes an argument against using certain slow
C++ features leads to bad performance, not an argument against C++
in general.

Also, I apologize for my poor malloc() style that about 10 people
pointed out. :) Obviously, I've gotten into a habit of doing it
in a bad way. I think it may be because I ran into a compiler that
would only allow the type name in sizeof() years ago, although that
is obviously not a good reason to keep doing it...

- Logan
 
I

Ian

Keith said:
One more question. In C, if two libraries use the same identifier,
it's difficult or impossible for a program to use both libraries.
Using a library-specific prefix can avoid this, but if two libraries
use the same prefix you still have the same problem.

Suppose two C++ libraries use the same namespace identifier, say
"foo". Is it possible to use both libraries by aliasing one or both
of the namespaces? For example, could the program refer to one
namespace as "foo1" and the other as "foo2"?
One solution would be to wrap one within another namespace, for example

foo1.h:

namesapce foo1
{
# include "someFoo.h"
}

foo1::foo::fun();

Ian
 
W

Walter Bright

Ulrich Eckhardt said:
Logan said:
For example, C++ allows you to do this:
int *i = new int[100];
Also, let's not use bad programming habits as example, both your lines are
examples of bad code.

// C++
std::tr1::scoped_array<int> i(new int[size]);

This modern trend of C++ to deprecate the straightforward constructs and
replace them with tedious ones is going to drive the language towards
unusability.

-Walter Bright
www.digitalmars.com C, C++, D programming language compilers
 
M

Malcolm

Ian said:
Is it? No one's told me... how do you think vector gets its memory?
This is exactly the sort of problems people have.
You're out of date and no one has bothered to tell you.

The modern consenus is that arrays shouldn't be used, and (less firm)
objects shouldn't be allocated with new. You should use a managed array
instead.

Once you start trying to mix arrays and dymanic objects with stl controlled
sequences, you really get into trouble. Hence the wisdom of the rule.

Of course if you are implenting a controlled sequence, there must be some
way of getting the memory - so that would be the one exception.
 
T

Thad Smith

Walter said:
There is one case where using a C++ compiler for C code may increase
performance - C++ uses a different function calling convention than C, a
faster one. The reason C compilers don't adopt it is for binary
compatibility with C compilers that predate function prototypes.

How important is binary compatibility with an older compiler? It
would seem normal to recompile source for new compilers. Aren't there
differences between compilers that pass some parameters in registers
vs. all on stack? In C, you could easily use called function stack
cleanup for all non-variadic functions, I would think. The compiler
could even have a compatibility mode, for caller cleanup, and
different entry point naming prefix for faster calling mode, couldn't
it?
 
J

jacob navia

Keith Thompson a écrit :
For example, C++ allows you to do this:

int *i = new int[100];

There is no reason the performance of this should be any worse than
the C equivalent:

int *i = (int *) malloc (100 * sizeof (int));

But, which one is easier to write? Also, will the compiler catch
the error for you if you accidentally change the second one to this?

double *d = (double *) malloc (100 * sizeof (int));


No, which is why the recommended way of writing that is

double *d = malloc(100 * sizeof *d);

better
double *d = malloc( sizeof(double[100]) );
 
I

Ian

Malcolm said:
This is exactly the sort of problems people have.
You're out of date and no one has bothered to tell you.
Nope, C++ (along with C and others) is my bread and butter, so I keep up
to date.
The modern consenus is that arrays shouldn't be used, and (less firm)
objects shouldn't be allocated with new. You should use a managed array
instead.
Ah, now I see your context. Yes, this has been the case for since the
STL became part of the language standard. However, containers are often
used to hold (ideally managed) dynamic objects.
Once you start trying to mix arrays and dymanic objects with stl controlled
sequences, you really get into trouble. Hence the wisdom of the rule.
Hence smart pointers, the 'modern' way of managing the lifetime of
dynamic objects. There is no need in C++ to work with raw pointers. As
I've said before on this thread, the is very useful feature in kernel code.
Of course if you are implenting a controlled sequence, there must be some
way of getting the memory - so that would be the one exception.
Exactly, by providing one's own new and delete operators, code can more
easily be moved from one environment (user space) to another (kernel space).

Ian
 
W

Walter Bright

Thad Smith said:
How important is binary compatibility with an older compiler?

Critical. For example, the operating system ABI's are normally C interfaces.
It would seem normal to recompile source for new compilers. Aren't there
differences between compilers that pass some parameters in registers
vs. all on stack? In C, you could easily use called function stack
cleanup for all non-variadic functions, I would think. The compiler
could even have a compatibility mode, for caller cleanup, and
different entry point naming prefix for faster calling mode, couldn't
it?

Many C compilers offer extensions for more efficient calling sequences, but
they are non-standard.

Walter Bright
www.digitalmars.com C, C++, D programming language compilers
 
W

Walter Roberson

Walter Bright said:
Walter Roberson said:
We're talking about performance of using C vs C++ for a project. Nothing in
either standard mandates a word about performance, and nobody said they did.
However, in the real world for real CPUs and real compilers, that
implementation difference does exist for the reasons mentioned.

You stated that "C++ uses a different function calling convention than C".
You admit that the standards say nothing about calling conventions,
but try to justify your statement by saying that the differences DOES
exist.

Your statement is readily disproved.

SGI IRIX 6.5 with the N32 or 64 ABI uses the same calling convention
for ALL languages.

http://techpubs.sgi.com/library/tpl.../SGI_Developer/MProAsLg_PG/sgi_html/ch07.html

I'm not quite sure what you mean by "callee cleans the stack",
but step 8 of the N32 and 64 ABI for IRIX is "Clean up the stack"
which occurs immediately before step 9, "return".

There's a lot more to picking a language for a particular project than what
the standard says.

So you had a good experience with ONE C++ compiler. That's nice.
And it proves nothing about how C or C++ generally handle calling
conventions.

If you had said that "On -some- systems, C++ does X while C does Y"
then you might have been correct... but that's obviously a
QOI issue and other compilers might have completely diferent
QOI's.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,139
Latest member
JamaalCald
Top