Adapting software to multiple usage patterns

J

jacob navia

Richard Heathfield a écrit :
That's an interesting belief, but not one that is universally held.


That depends on whether you consider the library to be a part of the
language. Some do, others don't.

You have the situation now:
All programs of a minimum complexity need to use lists, hash tables,
and other containers. Since there is no standard all those programs
have a "utilities.c" module where they have ad hoc container libraries.

When you merge the code bases you see that the list package A is not
compatible with list package B. Complexity of porting increases.

When you see
c = Get_nth(a,b);
You do not know immedately what it does. The language is more complex
because a common vocabulary is missing and you need to figure out
what "Get_nth" does.

The language is simpler if we use a common vocabulary for common tasks like
lists.
Except that many programmers will look at any such standard and find
it wanting in some respect or other - e.g. it's too complex, or too
slow, or whatever.

Sure. But much more will say:

AT LAST!

I do NOT need to rewrite a list package AGAIN!

And so they'll go roll their own anyway.

C has been always like that, and if you do not include stdio.h
you can roll your own I/O system. ANd there will be always people
that like to roll their own. They will be able to do that in the future.

The container library is for people that want to write THEIR software
and not rewrite a list package AGAIN!
This
already happens, by the way - for example, people write their own
little parsing libraries rather than use strtok.

So, you would say that strtok should be banned?

Besides the problems of multithreading with strtok are known. Maybe
you should consider that that could be a reason isn't it?
That's what your container library is pointing towards.

The library is written in standard C. I do not see where I am
doing C++. Obviously if you think that an abstraction like
containers is too much for C then please say it so.
Here I have to disagree. Just because something no longer changes,
that doesn't mean it's of no use. I have a five-eighths spanner which
I've owned for over twenty years. It hasn't changed at all over those
twenty years, but it still does its job perfectly well.

Sure. Because it is completely dead. Or you are going to argue that
the spanner is alive?

Languages are used by living PEOPLE and that's why they evolve
with time, because the PEOPLE that use them evolve, as people always do.

The "life" analogy is interesting, but you have not yet convinced me
that it is appropriate. C isn't a living creature.

Of course not. "C" is not alive. The PEOPLE that use "C" are alive, and
that is why C evolves!
It's a formal
system (or at least it's reasonably close to being a formal system).

I think that fgormal logic theory will evolve enough so that end of this
next decade they will be able to formalize C 100%. Until then, C is just
a convention used for communicating with a machine.
It can't die because it isn't alive. We can choose to stop using it
if we like, but that won't kill it because it isn't alive.

See above.
It is certainly a good all purpose programming language. You don't
need to add a standardised container library to make it so.

Well it is strange that the person that says this has written a
thick book about lists, and all kinds of containers.

True, that book stays always at a simplistic model, without ever
delving deeper into the problems of organizing data structures.

For instance the lists malloc for each element, etc. No performance
considerations, no generalization, etc.

I can't explain this to you. If you consider the situation now as
excellent, you are beyond help.

It is missing because any interface proposal is bound to have more
opponents than supporters.

<snip>

I am prepared to hear people like you:

"It will not work"
"We do not need it"
"Roll your own list package each time you start a project"
"Standards are just cumbersome"
"C is like that"
"The spirit of C is against that"


Who cares?

What is important in life is to try to better the environment
where you live, to improve things, to BUILD.

The passive people that are always saying that the best thing is to do
nothing are best ignored. It is a pity that instead of collaborating
in this project you just choose to fight it.
 
S

Seebs

But I do not want at all to start a flame war against C++.
What I want is the C equivalent: simpler, faster, that can be used
widely and make C a better language.

Make a variant, then. Objective-C is actually pretty good; it doesn't
pretend to be C, and it works nicely.
That would mean that there is no future for C.

No, it wouldn't.

It would mean the future for C is to stay simple.

The solution to "other languages are too complex" is not "let's add
complications to this one".
At the same time I see many things in C++ that are very good ideas
and I have tried to bring them to C. Software construction should be
about that: software construction and not "group feelings"...

Again, this would be a great opportunity to explore developing a variant
language, I think. But so far, I'm not convinced that things like a
container library actually simplify things. I would rather have a list
library, and an array library, and if I have to change from one to the other,
well, then I have to change some things. Since I almost certainly want
to change a lot of things along with that restructuring, that's not really
a big problem, from my point of view.

-s
 
K

Keith Thompson

jacob navia said:
Gareth Owen a écrit :

Well, I have spent the last 10 years writing a C99 compilation system.
I am surely not against C99!

I was just telling you about the attitude of some people here.

No, you're not; you're merely misunderstanding the attitude of some
people here.

Some people have probably expressed some anti-C99 sentiments, but
the vast majority of what I think you're interpreting as anti-C99
remarks have been based entirely on the fact that C99-conforming
compilers are not universally available.

Speaking for myself, I'd like to be able to use C99 (I like some of
the features and can ignore others), but I'm hesitant to do so until
I can rely on full C99 support in the same way that I can currently
rely on full C90 support. There's very little anyone other than
an implementer can do to change that (and I applaud you for doing
your part, even though it's only helpful for Windows programming).
 
S

Seebs

To evolve, yes. For instance this proposal about a container library
is an evolution that doesn't add any new complexity to the language.

Of course it does.

The library is part of "the language".
C remains exactly as it was before but we would have a common interface
for using lists, hash tables, bitstrings and other containers that would
allow that most programmers would not need to reinvent this thing
over and over when they program in C.

I have never in my life invented that thing.

I have written a handful of list implementations, most of which would not
have been able to effectively (IMHO) use the container library. I have
written a couple of implementations of array-like things. My string library,
flawed though it may be, had perfectly adequate implementations of both lists
and flexible arrays.
I disagree, and I believe that C is a good all purpose programming language.
It needs to have a better library and one of the most important things
that is missing is a common interface for containers.

Again, I disagree, because I usually find that a common interface for
containers is counterproductive for a lot of code.

See... Fundamentally, a container interface is only part of the interface.
Really, you need inheritance to do a good job, because there are things
which make sense to do to lists, but which do not make sense to do to
arrays, and vice versa. Sure, "iterate" and "add" are easy for both...
But not everything is so similar. In OO languages, you can have generic
containers, and then have lists and arrays which are also containers, but
have their own features.

You could probably do this thanks to the magic of common initial structures,
etcetera, but somewhere around there, you've basically implemented
inheritance, and if you're implementing inheritance in C, I think something's
gone wrong. And if you aren't implementing inheritance, "containers" are
the wrong layer of abstraction.

My guess is that you'd find a lot more interest in good, clean,
implementations of singly-linked and doubly-linked lists, and flexible
arrays, as three separate types of things. A container implementation
feels very much like it's too much an OO abstraction, and C's really
not the best place to do that.

-s
 
S

Seebs

All programs of a minimum complexity need to use lists, hash tables,
and other containers. Since there is no standard all those programs
have a "utilities.c" module where they have ad hoc container libraries.

No. They have ad-hoc list libraries, or ad-hoc tree libraries.

I have never seen a container library in C. Ever.
When you merge the code bases you see that the list package A is not
compatible with list package B. Complexity of porting increases.

Uh, no.

If you have different lists, they're used in different ways by different
code on different objects.
When you see
c = Get_nth(a,b);
You do not know immedately what it does. The language is more complex
because a common vocabulary is missing and you need to figure out
what "Get_nth" does.

I have never seen such a function. Ever.

I've seen lists used for list-like things, in which case, no one cares about
the Nth item; they care only about iterating to find an item with a given
quality, or about finding the next item.

If someone wants get_nth(), what they do is make a an array and write a.
The language is simpler if we use a common vocabulary for common tasks like
lists.

I agree that this could, potentially, help.

However, containers are a layer of abstraction too far from what would
be useful.
AT LAST!

I do NOT need to rewrite a list package AGAIN!

I haven't had to rewrite a list package since the mid-90s; either I've
come to a project with a well-defined existing one, or I've had one of
my own lying around.
The container library is for people that want to write THEIR software
and not rewrite a list package AGAIN!

Make a list library, and you'll find buy-in for that, I think.
The library is written in standard C. I do not see where I am
doing C++. Obviously if you think that an abstraction like
containers is too much for C then please say it so.

It is, because "container" hides crucial information about implementation
costs which is part of what C programmers expect to know about an interface.
Of course not. "C" is not alive. The PEOPLE that use "C" are alive, and
that is why C evolves!

The people using spanners are alive, but spanners don't seem to need to change
much.
The passive people that are always saying that the best thing is to do
nothing are best ignored. It is a pity that instead of collaborating
in this project you just choose to fight it.

It's not that we should do "nothing". It's that this particular thing does
not appeal, for pretty much the same set of reasons we've pointed out all
along.

Do a good list library, and I think you'll find takers. I posted an example
of one to clc once in the mid-90s and a couple of people grabbed it and used
it.

-s
 
C

Chris M. Thomasson

Seebs said:
Again you confuse function pointers and function tables! Your comments
in the other thread about the performance cost of virtual methods were
totally unrelated to the question of the performance cost of function
pointers.

Function tables are certainly possibly part of a well-understood C
interface,
but they're usually fairly closely tied to what's being done.
"Containers" is a very unlikely level of abstraction for a lot of use
cases.

Fundamentally, embedding a table of function pointers in an object is
pretty
unlikely to make it into the standard.

I think that using vtables to implement an abstract interface technique for
very simple data-structures (e.g., list, tree, array) is probably "overkill"
in most cases. I personally enjoy using intrusive data-structures; think
along the lines of:

http://groups.google.com/group/comp.lang.c/msg/533fcd7d743171c1

http://groups.google.com/group/comp.lang.c/msg/78308e18a53da752
 
S

Seebs

I think that using vtables to implement an abstract interface technique for
very simple data-structures (e.g., list, tree, array) is probably "overkill"
in most cases. I personally enjoy using intrusive data-structures; think
along the lines of:

Interesting! I hadn't thought of the CONTAINS() hack, so it hadn't
occurred to me to try it that way. My solution, which is a bunch simpler
but not as flexible, was to define 'struct list' as starting with a
'struct list *next'... Then if 'struct foo' starts with 'struct foo *', you
can cast it to a list and everything works.

Your solution is prettier, I think.

-s
 
C

Chris M. Thomasson

jacob navia said:
Seebs a écrit :

A list is the right structure when it doesn't grow too much. But you
know as well as everybody else that requirements change, and data
tends to grow, and that list that was OK for 500 elements it just
doesn't cut it with 5000: you need a better list, with better
heap management that doesn't call malloc for each element to
be added to the list. And then the list is out when you need
50000 elements. You need an array that is flexible, etc.

At each change you need to rewrite all data access!

Nit pick: Not all data-structures are compatible with every access pattern.
Perhaps the programmer wants a double linked-list because she will be
frequently adding and removing objects from random locations. In this case,
the access pattern is "built in" and changing to another structure with
different complexity for the normal access pattern can drastically reduce
performance.

Also, can I specify exactly how much memory one of you're containers will
use? Perhaps I need to make sure that the container only allocate memory
residing on the calling threads stack:


char buffer[8192];

list = list_create(sizeof(foo), buffer);

[...]

list_destroy(list);


I can eaisly do this with simple intrusive container:

http://groups.google.com/group/comp.lang.c/msg/533fcd7d743171c1


and simple region allocator:

http://pastebin.com/f37a23918




You can use it like:
_________________________________________________________________
#include <ralloc.h>


struct foo {
struct foo* next;
};


void crunch() {
char local_buffer[1024];
struct region local_region;
struct foo* head1 = NULL;
struct foo* head2 = NULL;
size_t i, r;

rinit(&local_region, local_buffer, sizeof(local_buffer));

for (r = 0; r < 1024; ++r) {
size_t c = 0;

for (i = 0; i < 64; ++i) {
struct foo* foo = ralloct(&local_region, 2, struct foo);
if (foo) {
foo->next = head1;
head1 = foo;
++foo;
foo->next = head2;
head2 = foo;
c += 2;
}
}

while (head1) {
head1 = head1->next;
--c;
}

while (head2) {
head2 = head2->next;
--c;
}

assert(! c);

rflush(&local_region);
}
}


int main(void) {
crunch();
crunch();
crunch();
return 0;
}
_________________________________________________________________




IMVHO, that's kind of cool... ;^)





BTW, the alignment hack is fairly nasty! Try not to throw up to much...




Anyway, can I use custom allocator for you're containers?
 
N

Nick Keighley

But you shouldn't have exposed your choice of data structure to the
application
level code anyway. It all should have been hidden away behind an
abstraction
anyway. The application wants to add things, remove things and find
things
it shouldn't care if it's an array, a linked list or a relational
database.
Changeing the container type is not expensive becasue it involves
rewriting
one thin library.
Only if your access pattern is list like.

You may not know how big the system is going to get. Or you may
be concentrating on getting other things right first. If things
are being addded and removed semi-randomly than a balanced tree
may be the right thing but an array ot list might be ok for a first
hack.

It's not necessarily the size, it might be frequency of addition. If the
program runs for a year adding 100 elements to the list per day then the
overhead of malloc might not be significant.


Hmm. Inserting an element half way through could be problematic.

Which a well-designed program confines to a small part of the code.
You should only be caught by this once (at worst) because after that
you
will have Refactored Mercilessly.
I've not had any data usage change by that much. I would consider it to
be a sign that it was not well specified in the first place.

I've seen an application scale from a handful of thingies (an
important
measure of the system's load) to thousands of thingies. Admittedly
this
was known from the start.

yes

I've never had them change that much. If it might happen that I would
possibly design a suitable flexible interface.

I think Jacob wants the flexibility in his library. Note even with C++
which has a set of generic containers I would still say hide the
choice
of container from the application code.


This is comp.lang.c we don't care about harming C++. This is just your
weird
paranoia speaking.

No it isn't. It just happens that a number of improvements you have
suggested have not been considered appropriate by a lot of people.

I happen to consider the addition of threading support to the C standard
to be interesting.

It isn't.

C++ does seem to be a bit of a monster. I think this is one reason
people resist adding complexity to C. I'm not sure I completly agree
with
them, but I see where they are coming from.
I'm not fond of what I've seen of C++, so I would probably pick one of
the other many languages out there if I wanted the kinds of features you
are proposing.
The library I presented [...] is a proposal for a standard way to use
containers what would give C a boost.

I think the C++ already took that name :)

You seem to think that discussing something means agreeing with you.
yes



For my usage, malloc is abstract enough. I don't need GC, and have never
seen a need for alloca (I don't have a need for flexible arrays either).

flexible arrays can be nice. I'd hide the malloc() in a library.
o Software specialization and subclassing (This was the original theme I
wanted to discuss with "Adapting software to multiple usage patterns")

I can't say I've a need for that, not in the was you are doing it. I do
have stuff with indirection through function pointers, but that is not
working in the same [way] as your interface.

I've done similar-ish things but not with containers. It doesn't feel
right.
The C++ invented a whole major language construct (templates) to avoid
using inheritance (which is what your function pointers look like) to
implement containers.
Those are different topics.


Plenty of people are interested in C, just not in your container library.

If you aren't for me you must be against me...
 
P

Phil Carmody

Seebs said:
Interesting! I hadn't thought of the CONTAINS() hack, so it hadn't
occurred to me to try it that way. My solution, which is a bunch simpler
but not as flexible, was to define 'struct list' as starting with a
'struct list *next'... Then if 'struct foo' starts with 'struct foo *', you
can cast it to a list and everything works.

Your solution is prettier, I think.

His solution is just like container_of() from the linux kernel -
used absolutely everywhere. It permits items to be on several lists,
which I consider to be an essential feature of any library (given
that it has no overhead compared to being on only one list). In
comparison to the linux container_of(), however, Chris's solution
is the bloody mona lisa.

However, I can't say that having SLIST_INIT as a noun and slist_init
as a verb is my kind of thing.

Phil
 
N

Nick Keighley

Gareth Owen a écrit :


I suppose you meant "fewer optimizations". Yes, but it has already
more or less 20-30% more speed than the C++ containers and uses
more or less the same memory for huge lists of 50 million items.

Now this surprises me! I would have thought a C++ would be able
to get more speed out of template code than your explicit vtable
could achieve. But empirical measurement trumps "I would have thought"
every time!
With specialization it can have more speed than C++ can ever attain.

again, I'm surprised.

Obviously since there is no C container library :)

And yes, "algorithm" part is surely not going to be ported to C...
most people I know using C++ never use that part of the STL and just have
a blank stare when I mention  it... Too complex!

I never thought it was "complex" just seemed unnecessary hassle
(I'd have to look it up) to do very little. I've used some of the
search

I'd never thought swopping containers was *that* easy.
Sure. You see, why then can't we do it in C? Why only in C++?

I'm not sure you can do it *even* in C++
Let's do it in C because is much SIMPLER since everything is open
for you to examine and modify.

Sometimes it's better if some of the machinary is hidden.
The vtable is not a mystery that
only compiler people know about. It is there, open for you to hack
as you wish.


That would mean that there is no future for C. And, as I have stated many
times, I do not believe that.

and as other people have said many times, resisting the piling on of C+
+
features to C does not mean that C has no future.
A simpler language is better than a complex one.

That needs decorating with a few weasel words. If it were universally
so
then we'd all be programing in cut-down Pacal. Darmouth BASIC anyone?
Why?

Because, contrary to the exponential growth of hardware, brain hardware
is kind of FIXED, and there is a much smaller limit to the amount of
computer language trivia that your brain is able to swallow without
indigestion.

The way to handle complexity is with abstraction. This is engineering
101

That ship has long sailed and C++ has grown beyond what a human being
can understand. Not even the creator of the language can introduce a
modification now, because the complexity of C++ is beyond what he
himself can manage. After several years working on "concepts", he was
forced to accept that he can't do it... The "concepts" debacle show
us that complexity grows without limit and eventually it makes the
whole language impossible to use correctly.

I wasn't sure if I should laugh or cry over concepts. Trouble is large
chunks of the new standard are heavily based on the presumption that
concepts *could* be made to work.
What I want is to go on developing C. You can make a positive contribution
here, if you wish. You can propose things, and I am not a zealot that
will start fighting language wars. I have to use C++ at work, and
that is why I am more and more convinced that the future is C and
not C++.

At the same time I see many things in C++ that are very good ideas
and I have tried to bring them to C. Software construction should be
about that: software construction and not "group feelings"...

I like constructors, destructors, exceptions (though exception safe
code
is "fun"), and the container library. Extensible io streams have
their
good points but somehow don't feel quite "right"
Thanks for your contribution.


--
"If you think C++ is not overly complicated, just what is a protected
abstract virtual base pure virtual private destructor, and when
was the last time you needed one?"
-- Tom Cargil, C++ Journal.


In the development of the understanding of complex phenomena,
the most powerful tool available to the human intellect is
abstraction. Abstraction arises from the recognition of similarities
between certain objects, situations, or processes in the real world
and the decision to concentrate on these similarities and to ignore,
for the time being, their differences.
- C.A.R. Hoare
 
N

Nick Keighley

Here I have to disagree. Just because something no longer changes,
that doesn't mean it's of no use. I have a five-eighths spanner which
I've owned for over twenty years. It hasn't changed at all over those
twenty years, but it still does its job perfectly well.

and your grandfather would have recognised it

[...] C isn't a living creature. It's a formal
system (or at least it's reasonably close to being a formal system).

Isn't that on par with "only a little bit pregnant?"

<snip>
 
J

jacob navia

Gareth Owen a écrit :
Really? You think a loop containing

sum += *(double *)dv->lpVtbl->GetElement(dv,i);

which has an explicit cast, two indirections and a pointer dereference
is as clear as

double mean = accumulate(vec.begin(),vec.end(),0.0) / vec.size();

I simply can't agree.

Of course, you are used to C++. And you are willing to pay for it.
(1) You can hide all that complexity with the macro I suggested
that hides everything in a clear fashion:

for (i=0; GetCountVector(dv); i++) {
sum += GetElementVector(dv,i,double);
}

I haven't used those macros because I think C programmers should be
used to complex expressions...

(2) C++ does exactly the same thing under the hood.
Actually, I'm slightly horrified you'd even say
that. If I wrote your line, and probably refactor it into two or
three clearer statements and trust the compiler to glue it back
together. And it still wouldn't have the clarity of the C++.

Maybe. But this is a question of a larger context. The problem with
the "clarity" of C++ is that it has a high COST, that you pay at
each usage. The cost of a much more complex language.

But let's stop this language war right here. In C, you have explicit
casts because no other type of cast is there.

I repeat:

I am not trying to steal "market share" from C++. It is there and has good
and bad features. I just want to improve C.
No one, I think, is arguing against code reuse (although they might
bristle at the standardisation of code they). Well, how about,
instead of pushing for standardisation, you start a project that will
become the C equivalent of Boost? Pure C89, free (in some sense) to
use and modify, bundled with lcc-win and anyone else who'll take them.

I am doing exactly that.
C programmers will decide whether they want them. If the demand is
there, a user community will grow up who'll greatly help your push for
standardisation. If there's no demand, standardisation would be a
waste of time.

Well, that is what I am trying to do.

Thanks for your participation.
 
N

Nick Keighley

Uh, no.

If you have different lists, they're used in different ways by different
code on different objects.

until you want to move stuff from one part of the code to another.
I know a program that has three different sorts of string. It's
irritating.

It's not that we should do "nothing".  It's that this particular thing does
not appeal, for pretty much the same set of reasons we've pointed out all
along.

we must do something, this is something therefore we must do it.

Also known as TINA, There Is No Alternative
 
T

Tim Rentsch

Richard Heathfield said:
[snip]

[...] C isn't a living creature. It's a formal
system (or at least it's reasonably close to being a formal
system).

Isn't that on par with "only a little bit pregnant?"

Permaybehaps. I think if you focus only on the subset of C that always
exhibits well-defined behaviour (i.e. ignore all programs that invoke
UB or USB or IDB), it's not unreasonable to call that subset a formal
system.

Now there's a laugh. C has nothing even vaguely resembling
a formal semantics.
 
N

Nick Keighley

In said:
On 14 Oct, 21:42, Richard Heathfield <[email protected]> wrote:
C [is] a formal system (or at least it's reasonably close to being a
formal system).
Isn't that on par with "only a little bit pregnant?"

Permaybehaps. I think if you focus only on the subset of C that always
exhibits well-defined behaviour (i.e. ignore all programs that invoke
UB or USB or IDB), it's not unreasonable to call that subset a formal
system.

I'm not sure the undefined behaviour is a big problem. Mathematical
functions are not defined for certain inputs and that doesn't seem to
upset the mathematicians. I think Cs informality comes because pretty
much all the semantics are defined in english.
 
N

Nick Keighley

[C] needs to have a better library and one of the most important things
that is missing is a common interface for containers.

Again, I disagree, because I usually find that a common interface for
containers is counterproductive for a lot of code.

See... Fundamentally, a container interface is only part of the interface..
Really, you need inheritance to do a good job,

really? I thought C++ demonstrated that you don't need inheritance for
a decent set of containers.
because there are things
which make sense to do to lists, but which do not make sense to do to
arrays, and vice versa.  

....which is poorly modelled by inheritance

Sure, "iterate" and "add" are easy for both...
But not everything is so similar.  In OO languages, you can have generic
containers, and then have lists and arrays which are also containers, but
have their own features.

which is not how C++ did it...
You could probably do this thanks to the magic of common initial structures,
etcetera, but somewhere around there, you've basically implemented
inheritance, and if you're implementing inheritance in C, I think something's
gone wrong.  And if you aren't implementing inheritance, "containers" are
the wrong layer of abstraction.

My guess is that you'd find a lot more interest in good, clean,
implementations of singly-linked and doubly-linked lists, and flexible
arrays, as three separate types of things.  A container implementation
feels very much like it's too much an OO abstraction, and C's really
not the best place to do that.

[rambling stream-of-conciousness-stuff follows]
C++ mostly uses template instantiation to do containers but it does
rely on
objects having common properties (copyable, assignable, comparable
etc) and
the way C++ does that probably relies on inheritance. Hmm. perhaps
not.
perhaps you could do a template thingy without inheritance. It's a
common
interface you need rather than inheritance (just because C++ does
interfaces
via inheritance doesn't mean you have to do it that way)
 
G

gwowen

Of course, you are used to C++.

No. It's because I know what the english noun "vector",
means, and what "begin", "end" and "accumulate" mean.
One does not have to know C++ to deduce the meaning

VALUE = ACCUMULATE(BEGIN_OF_VECTOR END_OF_VECTOR)

Any programmer of any language can deduce what that means.
I'd expect a bright non-programmer to have a bloody good
stab at it. Can you make the same assertions about your
"equally clear" code?
And you are willing to pay for it.

You have not demonstrated how I pay for it.
I haven't used those macros because I think C programmers should be
used to complex expressions...

Really? Complex expressions are error prone and tend to be opaque.
I am used to complex expressions, but I stay away from them unless
I have to. If I can express complex ideas with simple syntax ...
well, I don't consider that disadvantage.
(2) C++ does exactly the same thing under the hood.

Of course it does. (And yet you claim, without measurement, that
yours is faster. I remain dubious of this claim.) But the fact
that it is under the hood makes my life easier. It's a benefit
to me that I can start it with a key and not a crank-handle.
It's a benefit to me that I can access things in a container
without having to use two indirections, a cast and a dereference.
Maybe. But this is a question of a larger context. The problem with
the "clarity" of C++ is that it has a high COST, that you pay at
each usage. The cost of a much more complex language.

You have not demonstrated this cost to me. It's a cost for
implementors, but I'm not an implementor. On the contrary.
C++ hides the implentation. This means that my program is clearer,
less error prone, more typesafe. And, because
I'm not allowed to mess with the vtable[0], the code can inline many
of the calls for which your library must use an (explicit) function
pointer.

The standard is more complex (brutally so) but my program is simpler.
But let's stop this language war right here. In C, you have explicit
casts because no other type of cast is there.

Well yes, but a container library that requires its user to cast the
results at every step is inconvenient to use and error prone.

[0] In fact, of course, C++ containers use templates not inheritance,
so vector<int> does not even use a vtable. They use template-ised
name-mangled direct function calls, so they don't use function
pointers at all. All the function resolution is done at compile/link
time. So, even without inlining, these direct function calls tend to
be quicker than calls through function pointers.

So your "C++ does the same thing under the hood" is not even accurate.
 
B

bartc

Gareth Owen said:
Really? You think a loop containing

sum += *(double *)dv->lpVtbl->GetElement(dv,i);

which has an explicit cast, two indirections and a pointer dereference
is as clear as

double mean = accumulate(vec.begin(),vec.end(),0.0) / vec.size();

You're not comparing like with like. The two statements do different things,
if I've deduced the meaning of the second one correctly.

What is the exact equivalent using your syntax? I suspect it might make your
point better because the first statement uses an extemely ugly way of
indexing an array or list so it can't be that bad even for C++!
 

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
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top