Why We Use C Than C++...

S

Sjouke Burry

Malcolm said:
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.
C++? C++? C++? C++? (Or wat are you talking about?)
Also I have used arrays (with no memory leak)
and avoided malloc successfully for the last 30+
years.
Malloc is fine if you need to build/shrinck
structures for exsample ,but it it not the
cure for every problem.
Use language features when you need them,and
not because somebody tells you they are the
latest and greatest.
 
T

Thad Smith

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

By non-standard, I assume you mean not compatible with older compilers,
not non-compliant with the C standard.
 
M

Michael Mair

jacob said:
Keith Thompson a écrit :
Logan Shaw <[email protected]> writes:

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

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

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

Nope; you missed the point (not accidentally, I am sure).
The aim is to avoid a second mention of the type, so that
type changes or copy-paste(-disaster) cannot cause errors.


Cheers
Michael
 
E

Emmanuel Delahaye

(e-mail address removed) a écrit :
Hi, Please help me in this regard...
All the kernel level programs are written in C... (i.e: Open Source
LINUX)... Why are they not using C++... I personally feel that C++ is
more easy to code than C... When i searched in our encyclopedia (i.e
Google), i came up with several answers, telling "C is much faster than
C++ and most kernal prgms uses only C" ... But why is it so...? Why
they use C for these OS based programs.. Please Help me with detailed
explanation...

AFAIK, C was invented before C++. The main systems (Unix, Linux,
Windows) have been written in C, just because C was considered as a
'portable assembler', allowing to drive the hardware (with some
extensions) on one hand, and to provide a sufficient level of
abstraction to build portable interfaces (API).

If this is possible in some other language, there is nothing that
prevents you to write a new system from scratch using this language
(except time and money, I guess). Good luck.
 
U

Ulrich Eckhardt

Walter said:
Logan said:
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 ;-)

There is a comparison between two non-equivalent pieces of code, so using
this as a measure for speed is just flawed. That's all I wanted to point
out.
Also, BTW, instead of saying exceptions are an overhead, you could as well
say that not having them is a disadvantage.
From what I've read, the overheads of exception support are quite high.

Can you give a quote/URL? From what I know, there is indeed an overhead and
early implementations of C++ didn't perform too well, but better
implementations have made the cost when not throwing an exception
negligible.

Uli
 
U

Ulrich Eckhardt

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"?

No. Those namespace aliases are just that, just as a typedef is just an
alias and doesn't change the symbol emitted to the linker (with the
exception of typedef'ing an anonymous type).

Ian, your solution doesn't work, it changes the declarations found in a
header, but it still doesn't change the symbols exported from a library.

No, I think in order to shoehorn two conflicting two libs into one program
one needs to resort to things like changing the linker symbols manually or
writing a wrapper lib that consists of a bunch of forwarding functions
with just a different name.
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.

I'm not sure that otherwise they wouldn't be worthwhile adding. Point is
that they could be added without breaking any existing code, they are
definitely no runtime overhead, because just a different syntax, and I
think they would indeed solve problems for which there is no solution:
Think about for example the Apache portable runtime library. If it had
used apache_runtime (let's just drop the portable) as prefix, everyone
would have to write
apache_runtime_file* f = apache_runtime_open("fou.texte");
Tedious. Very. That's the reason they chose apr_ as a prefix, which is much
shorter but then again bears the danger of conflicting. Using namespaces,
you could alias namespace apache::portable_runtime to just apr when using
it.

Uli
 
I

Ian Collins

Ulrich said:
No. Those namespace aliases are just that, just as a typedef is just an
alias and doesn't change the symbol emitted to the linker (with the
exception of typedef'ing an anonymous type).

Ian, your solution doesn't work, it changes the declarations found in a
header, but it still doesn't change the symbols exported from a library.
Yes, you are correct, my mistake.
No, I think in order to shoehorn two conflicting two libs into one program
one needs to resort to things like changing the linker symbols manually or
writing a wrapper lib that consists of a bunch of forwarding functions
with just a different name.
This would be the only workable solution.
 
K

Keith Thompson

Ian Collins said:
Yes, you are correct, my mistake.

This would be the only workable solution.

Changing the linker symbols manually is obviously extremely
system-specific, assuming it's possible at all. A wrapper lib sounds
like a good idea, but I would think the original library with the
conflicting names would still be part of the program -- unless you do
something equally system-specific to hide the original names.
 
M

Malcolm

Logan Shaw:
$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));


Ian
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.
There seem to be radical disagreements about what is and what isn't
idiomatic C++ code.

You can't sensibly do object-oriented programming in C, and in some
situations an object-oriented design is far superior to a procedural one.
But in my opinion trying to use C++ for bascially procedural code, with no
control about what language features will be used and which will be ignored,
is asking for trouble. That's why procedural programs are better written in
C.
 
I

Ian Collins

Malcolm said:
There seem to be radical disagreements about what is and what isn't
idiomatic C++ code.
True, that's bound to happen with an expressive language. C has the
benefit of being concise, although there are still disagreements on
style, for instance the current thread on variable declaration and
initialisation (this tends not to be an issue in the C++ world where
variables are declared where used).
You can't sensibly do object-oriented programming in C, and in some
situations an object-oriented design is far superior to a procedural one.
But in my opinion trying to use C++ for bascially procedural code, with no
control about what language features will be used and which will be ignored,
is asking for trouble. That's why procedural programs are better written in
C.
I still disagree with this. My introduction to OO was the xview
toolkit. Very C and very OO.

If you are using C++ for kernel/driver code, you have to work within a
set of constraints what define the features of the language you can use.
The evolutionary path from C to C++ has left a legacy of compiler
options to enable/disable language features (for backwards
compatibility). These options can be used to define the feature set a
programmer can use for a specific application.

There are many cases where C++ is a good choice for procedural code, the
ability to manage the lifetime of dynamic memory and locks is the one I
have found most useful in kernel space.
 
J

jacob navia

Ulrich Eckhardt a écrit :
Walter said:
Ulrich Eckhardt said:
Logan Shaw wrote:

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 ;-)


There is a comparison between two non-equivalent pieces of code, so using
this as a measure for speed is just flawed. That's all I wanted to point
out.
Also, BTW, instead of saying exceptions are an overhead, you could as well
say that not having them is a disadvantage.

From what I've read, the overheads of exception support are quite high.


Can you give a quote/URL? From what I know, there is indeed an overhead and
early implementations of C++ didn't perform too well, but better
implementations have made the cost when not throwing an exception
negligible.

Uli

I have studied the implementation of exceptions in gcc. There are
basically two methods:
1)SJLJ (set jump/long jump) style, where the cost for any function is
high even when NOT throwing any exceptions,
2) dwarf2 based tables, where the compiler describes in detail each
stack frame so that the runtime is able to figure out where it should
jump. This method is fast when not throwing exceptions since there
is no overhead, but it costs a LOT in RAM space since those tables
must be generated for each function, and that is surely not cheap in
space requirements. The tables need to be there even for functions that
do not use exceptions at all.

So, you can see, there is no free lunch...

jacob
 
J

jacob navia

Keith Thompson a écrit :
Changing the linker symbols manually is obviously extremely
system-specific, assuming it's possible at all. A wrapper lib sounds
like a good idea, but I would think the original library with the
conflicting names would still be part of the program -- unless you do
something equally system-specific to hide the original names.

Just build a dynamically loaded library (dll/so)

jacob
 
L

Logan Shaw

jacob said:
Ulrich Eckhardt a écrit :
I have studied the implementation of exceptions in gcc. There are
basically two methods:
2) dwarf2 based tables, where the compiler describes in detail each
stack frame so that the runtime is able to figure out where it should
jump. This method is fast when not throwing exceptions since there
is no overhead, but it costs a LOT in RAM space since those tables
must be generated for each function, and that is surely not cheap in
space requirements. The tables need to be there even for functions that
do not use exceptions at all.

My guess is they don't need to be there for functions which exceptions
cannot pass through, right?

In which case, wouldn't all those functions have to have some sort of
other code to deal with error conditions anyway, at least if they are
doing proper error handling and not just ignoring errors?

Which makes me wonder: are there situation where a program with
exceptions actually has more overhead than a program that does proper
error handling without exceptions? In other words, is it the case
that eliminating exceptions only reduces overhead if you also leave
out the proper error handling?

- Logan
 
J

jacob navia

Ian Collins a écrit :
Doesn't help with duplicate symbols.

Yes it helps, since you can rename the symbols within it,
hiding them from the rest of the world...
 
J

jacob navia

Logan Shaw a écrit :
My guess is they don't need to be there for functions which exceptions
cannot pass through, right?

No, ANY function can be passed by an exception handler
if it is not a leave function (doesn't call any other function)
in the absolute sense of the word, i.e. if it doesn't
*implicitely* call new() for instance, or if it doesn't
call some copy constructor, overloaded operator or whatever...

It would be quite impossible to the compiler to determine that
there is NEVER some path that directly or indirectly arrives
at that function so unless it is *really* evident the compiler
will generate the tables for each function.
In which case, wouldn't all those functions have to have some sort of
other code to deal with error conditions anyway, at least if they are
doing proper error handling and not just ignoring errors?

Which makes me wonder: are there situation where a program with
exceptions actually has more overhead than a program that does proper
error handling without exceptions? In other words, is it the case
that eliminating exceptions only reduces overhead if you also leave
out the proper error handling?

You can do a lot of error handling by relying on the
hardware:

If you set a hardware trap handler for "Segmentation violation"
then you can do:
int *a = malloc(sizeof(int[100]));
a[2] = 67;
and just suppose that if that crashes, the signal handler will
branch to the appropiate function...

jacob
 
J

jacob navia

jacob navia a écrit :
No, ANY function can be passed by an exception handler
if it is not a leave function (doesn't call any other function)

I think that should have been a "leaf function"....
Sorry
 
U

Ulrich Eckhardt

Not the only one. Using dlopen/dlsym or LoadLibrary/GetProcAddress, you can
load the same symbol from more than one lib. Of course, all this plays in
the real world (i.e. outside the standard) but still covers a reasonable
amount of systems.
Changing the linker symbols manually is obviously extremely
system-specific, assuming it's possible at all.

Last time I used it, I was pretty impressed by the capabilities of the GNU
binutils, in particular by objcopy, which can handle a whole bunch of
formats.

<snipped rant about signed binaries, digital restriction management etc
which will f*** it all up and that the whole world is evil and against me>

cheers

Uli
 

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

Forum statistics

Threads
474,173
Messages
2,570,937
Members
47,481
Latest member
ElviraDoug

Latest Threads

Top