Thursday, July 30, 2009

comp.lang.c++ - 25 new messages in 5 topics - digest

comp.lang.c++
http://groups.google.com/group/comp.lang.c++?hl=en

comp.lang.c++@googlegroups.com

Today's topics:

* New release of the Dynace OO extension to C - 16 messages, 8 authors
http://groups.google.com/group/comp.lang.c++/t/ee8689156295093c?hl=en
* Alternatives to C: ObjectPascal, Eiffel, Ada or Modula-3? - 3 messages, 3
authors
http://groups.google.com/group/comp.lang.c++/t/40783f7f814400c9?hl=en
* Printing the last item of a structure twice - 4 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/9fd75392aae26667?hl=en
* How to split this string correctly? - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/1845370483de2cfa?hl=en
* question on vector<char>::difference_type - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/0887bb3c0dd6545e?hl=en

==============================================================================
TOPIC: New release of the Dynace OO extension to C
http://groups.google.com/group/comp.lang.c++/t/ee8689156295093c?hl=en
==============================================================================

== 1 of 16 ==
Date: Thurs, Jul 30 2009 2:33 pm
From: "Tech07"

"Miles Bader" <miles@gnu.org> wrote in message
news:buo1vnya3xf.fsf@dhlpc061.dev.necel.com...
> "Tech07" <tech07@nospam.hia> writes:
>> Hence, I say RAII is only an incremental improvement, if any at all
>> considering the lock-stock-and-barrel shift needed for the C++
>> solution.
>
> Why is a "lock-stock-and-barrel shift" needed for C++?
>
> You can easily use very C-like subsets if that seems nicer...
> (e.g., "only class, no overloading, no templates, no exceptions")
>

If you have a C (only) compiler already, perhaps one you've build or a
hardware vendor supplied for embedded system development or something,
moving to C++ means changing the main development tool (from something which
is relatively simple to something which is complex). It may not be a
plausible option from many similar perspectives.


== 2 of 16 ==
Date: Thurs, Jul 30 2009 2:59 pm
From: Keith Thompson


"BGB / cr88192" <cr88192@hotmail.com> writes:
> "Squeamizh" <squeamz@hotmail.com> wrote in message
> news:c0927f54-f774-4c28-ad22-69ae3ee4e2b6@l5g2000pra.googlegroups.com...
> On Jul 30, 12:34 pm, "BGB / cr88192" <cr88...@hotmail.com> wrote:
[...]
>> nesting and using "local objects" in this way, is bad practice, FWIW...
>> granted, some newer compilers allow it (such as GCC), and it is part of
>> C99,
>> but this does not make it a good style.
>>
>> either all declarations are done at the top of the function, or the
>> function
>> should be split.
>
> <--
> First, you're wrong; declaring variables local to a block is legal in
> c89. Secondly, you labeling something as "bad practice" is
> meaningless without being accompanied by some sort of explanation.
> WHY is it bad practice?
> -->
>
> AFAIK, it is not legal in C89 (after all, if it had been legal since C89, no
> one would need mention it becomming legal in C99...).
>
> (note: by this, I meant internal blocks, such as with a for loop or if
> block...).
>
> it was only "made" legal in C99, and was informally legal in many compilers
> (much like the "//" comment syntax, which has worked damn near as long as I
> have been using C, but was also not legal until C99...).

You are mistaken.

Mixing declarations and statements within a block is illegal in C90,
legal in C99 and C++.

Declarations within blocks have been legal at least since K&R1; even
BCPL permitted them.

> anyways, it is bad practice:
> firstly, because we all know that variable declarations belong at the top of
> functions, and before any statements;

I'm afraid that isn't very convincing.

> secondly, because it needlessly obfuscates and dirties code to have
> declarations mixed in with executable statements;
> ...

I disagree. I prefer declarations to have a reasonably narrow scope,
and I sometimes introduce a block for the purpose of adding a local
declaration.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


== 3 of 16 ==
Date: Thurs, Jul 30 2009 3:02 pm
From: Phil Carmody


"Tech07" <tech07@nospam.hia> writes:
> "Alf P. Steinbach" <alfps@start.no> wrote in message
> news:h43drm$oij$1@news.eternal-september.org...
>>* BGB / cr88192:
>>> "Jerry Coffin" <jerryvcoffin@yahoo.com> wrote in message
>>> news:MPG.24ce9e0f1b1b78da9896e4@news.sunsite.dk...
>>>> In article <4a64925d.387669859@text.giganews.com>, cri@tiac.net
>>>> says...
>>>>
>>>> [ ... ]
>>>>
>>>>> Perhaps you could elaborate on your thought just a bit. In C it is
>>>>> easy enough to write the equivalent of constructors and
>>>>> destructors. Thus I might write a foo package with entry points
>>>>> for creating and deleting new foos. The create and delete routines
>>>>> will call malloc and free explicitly, of course, but that is
>>>>> trivial.
>>>> The crucial point is objects being destroyed automatically upon
>>>> exiting their scope. That's what makes the big difference -- for the
>>>> majority of objects (i.e. anything that can have automatic scope) you
>>>> don't have to deal with cleanup explicitly at all.
>>>>
>>>
>>> this is a "convinience" matter, not a "functionality" matter.
>>>
>>> it is slightly less convinient to use an API call for cleanup.
>>> so?...
>>
>> No, it's not primarily about convenience.
>>
>> Although it /is/ convenient. :-)
>
> While C gives the programmer no help, C++ "provides" only one stylistic
> approach: RAII.

Well that's one of the biggest loads of bollocks that's been cross-posted
to comp.lang.c in a long time. (Apart from the regular idiots who are
heppily killfiled.)

C++ provides practically _everything_ provided by C, so if C provides
anything which isn't RAII (which it does), then C++ does too.

Please evolve a brain before cross-posting again.

Phil
--
If GML was an infant, SGML is the bright youngster far exceeds
expectations and made its parents too proud, but XML is the
drug-addicted gang member who had committed his first murder
before he had sex, which was rape. -- Erik Naggum (1965-2009)


== 4 of 16 ==
Date: Thurs, Jul 30 2009 3:12 pm
From: "BGB / cr88192"

"Brian Wood" <coal@mailvault.com> wrote in message
news:fbe99bda-74a8-40ee-a697-608812365516@v36g2000yqv.googlegroups.com...
On Jul 30, 2:21 pm, Jerry Coffin <jerryvcof...@yahoo.com> wrote:
> In article <Podcm.46508$vp.1...@newsfe12.iad>, tec...@nospam.hia
> says...
>

<snip>

>
> > That's not impossible in C and not hardly "an order of magnitude" better
> > in
> > C++ just because of RAII. It's just incrementatlly better in a number of
> > scenarios. But again, if C++ isn't an option, then it behooves one to
> > R&D
> > something(s) consistent for use in C.
>
> 1) Decades of experience has shown that while it's _theoretically_
> possible to get it right in C, that in the entire history of C,
> there's probably never been even one nontrivial program that didn't
> have at least one memory management problem. For any practical
> purpose, that qualifies as "impossible".
>
> 2) The improvement is hardly "incremental" -- in typical cases, it's
> a lot _more_ than one order of magnitude improvement.
>
> 3) The number of scenarios where it provides a nontrivial improvement
> is extremely large -- I'd say well over 90% of all typical code can
> use RAII to manage the lifetime of most objects.
>

<--
I agree with the above except for the 90% figure. I don't
have anything to go on other than my opinion that RAII is
not as helpful in servers as in programs that run once and
exit. In run once programs I wouldn't argue with that
figure, but I don't consider those programs to be as
interesting as servers.
-->

yep, in the main cases it will help with, it is the cases where manual MM is
relatively trivial, thus serving as essentially a shortcut (not having to
manually free resources or invoke destructors).

OTOH, for the cases where manual MM becomes non-trivial (AKA: when one no
longer knows who owns an object, or where or how many references there are),
RAII wouldn't really help much either.


then, once again, it amounts to the same issue and solution as before:
don't transfer ownership.


it is like arguing the "fundamental" differences between, say:

class Foo {
public:
Foo(int x, double y);
virtual int foo(int x);
virtual int bar(double y);
private:
int x;
double y;
};

and:
typedef struct Foo_s Foo;

struct Foo_fs {
int (*foo)(Foo *ctx, int x);
int (*bar)(Foo *ctx, double y);
};

struct Foo_s {
struct Foo_fs *fcn;
int x;
double y;
};


there is a difference, but it is modest.


side by side, one would see endless minor differences in the code, but that
is the issue here:
minor...

Foo *foo;

foo=new Foo(3, 4);
vs:
foo=FooAlloc(3, 4);

delete foo;
vs:
FooDestroy(foo);


foo->foo(5);
vs:
foo->fcn->foo(foo, 5);
or:
FooFoo(foo, 5); //basically, it is common to wrap "vtable" calls as
well...

...


but, then again, the proir poster may well claim that the above would not
really be C, unless one directly uses malloc and stupidly loses the pointer
somewhere, but oh well...

part of the (apparently much despised) power of C, is that it becomes common
to wrap the language to some extent... (and, no, not with huge amounts of
macros or a custom preprocessor...).

the differences in language tend more to lead to a "different" set of
styles, where something approached one way in one language may be approached
a little differently in another.


it is like the differences between using function calls and operator
overloading:
without operator overloading, it is typical to use function calls instead.

one can note that a function call is not as terse as an operator, but both
accomplish essentially the same purpose...


and, yes, I really have built 1/2 of Common Lisp in C...

== 5 of 16 ==
Date: Thurs, Jul 30 2009 3:15 pm
From: Ben Pfaff


Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:

> "Tech07" <tech07@nospam.hia> writes:
>> While C gives the programmer no help, C++ "provides" only one stylistic
>> approach: RAII.
>
> Well that's one of the biggest loads of bollocks that's been cross-posted
> to comp.lang.c in a long time. (Apart from the regular idiots who are
> heppily killfiled.)
>
> C++ provides practically _everything_ provided by C, so if C provides
> anything which isn't RAII (which it does), then C++ does too.

It's possible to use the C style of jumping to cleanup code at
the end of a function in C++.

It's possible to use RAII in C++.

It's difficult to combine these styles, however, since C++
prohibits jumping into a scope past a declaration of a non-POD
type or a declaration with an initializer. Although C doesn't
have non-POD types, it doesn't have the latter restriction either
(except for variably modified types).
--
Ben Pfaff
http://benpfaff.org


== 6 of 16 ==
Date: Thurs, Jul 30 2009 3:17 pm
From: "Tech07"

"Jerry Coffin" <jerryvcoffin@yahoo.com> wrote in message
news:MPG.24dba09afd6fa7f989714@news.sunsite.dk...

> 1) Decades of experience has shown that while it's _theoretically_
> possible to get it right in C, that in the entire history of C,
> there's probably never been even one nontrivial program that didn't
> have at least one memory management problem. For any practical
> purpose, that qualifies as "impossible".

It's one thing to say that "it scientifically provably can't be done in C",
it's quite another to say "well, 10 years ago I switched to C++ and I
haven't been back to C and applied what I've learned in those 10 years and
now I'm going to just pretend C is bad because I'm a C++ user now". You
totally seem to be doing the latter in some form. Perhaps the C++ paradigm
is holding you back and you honestly are blinded by it, I dunno. You go on
making your extreme and apparently extremely biased statements, I don't
care. For the record though, you are wrong, and I'm not going to continue to
respond to your vacuous statements.

>
> 2) The improvement is hardly "incremental" -- in typical cases, it's
> a lot _more_ than one order of magnitude improvement.

There's that big sucking sound again!

>
> 3) The number of scenarios where it provides a nontrivial improvement
> is extremely large -- I'd say well over 90% of all typical code can
> use RAII to manage the lifetime of most objects.

Again, RAII-like patterns are not the exclusive domain of C++, nor were
they invented by or in C++. And again, markettering any potential niceties
of C++ are off-topic in a thread where the obvious gist is improving C
unless you are able to apply that information towards solution in C. The OP
surely knew that C++ existed before he decided to embark on a framework
built for C.

>
> [ ... ]
>
>> Don't look now, but you have made unqualified extreme statements
>> above:
>>
>> "It's about giving yourself a fighting chance to create code that might
>> work
>> correctly."
>>
>> "This is a bit like saying it's slightly more convenient to build a
>> house
>> using a saw to cut the wood instead of turning a bunch of termites loose
>> and hoping they eat through the wood in exactly the way you need it cut."
>>
>> Do you expect the dude to just run out and get a C++ compiler after
>> unscientific/moot statements?
>
> None of these is extreme at all -- they're both pretty much literal
> fact.

You are encorrigible, I see. Good luck with that.

>> >
>> > Look back to the beginning of the thread -- it didn't start out as a
>> > discussion of whether there was ever a reason to use C. It started
>> > out with a claim that Dynace was categorically superior to C++, and
>> > at least strongly implied (if not quite directly stated) that there
>> > was never a good reason to use C++.
>>
>> But "claiming" that C++ is "categorically superior" to C or Dynace is OK?
>
> Nobody seems to have made such a claim. In fact, a quick check with
> Google shows that the post to which I'm replying was the first use of
> that phrase in the entire newsgroup this year!
>
> --
> Later,
> Jerry.


== 7 of 16 ==
Date: Thurs, Jul 30 2009 2:52 pm
From: "Tech07"

"Jerry Coffin" <jerryvcoffin@yahoo.com> wrote in message
news:MPG.24dba09afd6fa7f989714@news.sunsite.dk...
> In article <Podcm.46508$vp.1008@newsfe12.iad>, tech07@nospam.hia
> says...
>
> [ ... ]
>
>> You're exagerating with the analogy. Analogies are never good when
>> the issue is understood and you're only using one to argue (read,
>> "escalating analogy wars").
>
> No, I'm really not. When you write an API that requires manual de-
> allocation of memory, you're creating something that purely in theory
> _could_ work correctly -- but decades of experience has shown that
> for nearly any practical purpose, it simply won't.

Who was suggesting "manually deallocating memory"? Not me. Indeed, the
subthread herein is that techniques for doing such is C exist. Creating code
in a transactional style is not the exclusive domain of C++ by any means.
Apparently you don't have any of those techniques in your toolbox, indicated
by the extreme analogy you used (either that or you're inappropriately
marketeering for C++ as so many seem to do).

>
> [ ... ]
>
>> You're suggesting that the only options are: 1.) C++ RAII, or 2.)
>> "manual" coding using C. Another alternative is to invent something
>> (s) new, perhaps to get "adequate" coverage of the concerns. In C,
>> of course, one has no choice but to invent something, C++ may not
>> be an option, or risk the kind of inconsistency you described
>> above.
>
> I'm not suggesting that nobody could possibly write a usable
> alternative in C. Up until now, however, you didn't even seem to
> understand what kind of problem needed to be addressed. So far, you
> haven't suggested any real alternative to RAII either, just suggested
> the possibility that some alternative could be invented. If you can
> come up with a better alternative, I'm all for it -- RAII certainly
> isn't perfect by any means. At the same time, you haven't suggested
> any real alternative at all, not to mention a superior one.

You're missing the key point: Using C is a constraint of the discussion. C++
mechanisms are valid in the thread ony as research perhaps to get ideas for
alternative implementations in C. My statement that you are way off base
with your analogy is not just a theory, it is something I know to be true.


== 8 of 16 ==
Date: Thurs, Jul 30 2009 3:20 pm
From: "Tech07"

"Phil Carmody" <thefatphil_demunged@yahoo.co.uk> wrote in message
news:874ostkewc.fsf@kilospaz.fatphil.org...
> "Tech07" <tech07@nospam.hia> writes:
>> "Alf P. Steinbach" <alfps@start.no> wrote in message
>> news:h43drm$oij$1@news.eternal-september.org...
>>>* BGB / cr88192:
>>>> "Jerry Coffin" <jerryvcoffin@yahoo.com> wrote in message
>>>> news:MPG.24ce9e0f1b1b78da9896e4@news.sunsite.dk...
>>>>> In article <4a64925d.387669859@text.giganews.com>, cri@tiac.net
>>>>> says...
>>>>>
>>>>> [ ... ]
>>>>>
>>>>>> Perhaps you could elaborate on your thought just a bit. In C it is
>>>>>> easy enough to write the equivalent of constructors and
>>>>>> destructors. Thus I might write a foo package with entry points
>>>>>> for creating and deleting new foos. The create and delete routines
>>>>>> will call malloc and free explicitly, of course, but that is
>>>>>> trivial.
>>>>> The crucial point is objects being destroyed automatically upon
>>>>> exiting their scope. That's what makes the big difference -- for the
>>>>> majority of objects (i.e. anything that can have automatic scope) you
>>>>> don't have to deal with cleanup explicitly at all.
>>>>>
>>>>
>>>> this is a "convinience" matter, not a "functionality" matter.
>>>>
>>>> it is slightly less convinient to use an API call for cleanup.
>>>> so?...
>>>
>>> No, it's not primarily about convenience.
>>>
>>> Although it /is/ convenient. :-)
>>
>> While C gives the programmer no help, C++ "provides" only one stylistic
>> approach: RAII.
>
> Well that's one of the biggest loads of bollocks that's been cross-posted
> to comp.lang.c in a long time. (Apart from the regular idiots who are
> heppily killfiled.)
>
> C++ provides practically _everything_ provided by C, so if C provides
> anything which isn't RAII (which it does), then C++ does too.
>
> Please evolve a brain before cross-posting again.
>

You should learn how to read and comprehend before you start blathering. And
if you don't understand, ask.


== 9 of 16 ==
Date: Thurs, Jul 30 2009 3:27 pm
From: "BGB / cr88192"

"Keith Thompson" <kst-u@mib.org> wrote in message
news:lnvdl9ygr6.fsf@nuthaus.mib.org...
> "BGB / cr88192" <cr88192@hotmail.com> writes:
>> "Squeamizh" <squeamz@hotmail.com> wrote in message
>> news:c0927f54-f774-4c28-ad22-69ae3ee4e2b6@l5g2000pra.googlegroups.com...
>> On Jul 30, 12:34 pm, "BGB / cr88192" <cr88...@hotmail.com> wrote:
> [...]
>>> nesting and using "local objects" in this way, is bad practice, FWIW...
>>> granted, some newer compilers allow it (such as GCC), and it is part of
>>> C99,
>>> but this does not make it a good style.
>>>
>>> either all declarations are done at the top of the function, or the
>>> function
>>> should be split.
>>
>> <--
>> First, you're wrong; declaring variables local to a block is legal in
>> c89. Secondly, you labeling something as "bad practice" is
>> meaningless without being accompanied by some sort of explanation.
>> WHY is it bad practice?
>> -->
>>
>> AFAIK, it is not legal in C89 (after all, if it had been legal since C89,
>> no
>> one would need mention it becomming legal in C99...).
>>
>> (note: by this, I meant internal blocks, such as with a for loop or if
>> block...).
>>
>> it was only "made" legal in C99, and was informally legal in many
>> compilers
>> (much like the "//" comment syntax, which has worked damn near as long as
>> I
>> have been using C, but was also not legal until C99...).
>
> You are mistaken.
>
> Mixing declarations and statements within a block is illegal in C90,
> legal in C99 and C++.
>
> Declarations within blocks have been legal at least since K&R1; even
> BCPL permitted them.
>

this is what I had meant...

you misunderstood what I had written...


>> anyways, it is bad practice:
>> firstly, because we all know that variable declarations belong at the top
>> of
>> functions, and before any statements;
>
> I'm afraid that isn't very convincing.
>

it is the case though...

for some things, it is just the case that they are that way...


>> secondly, because it needlessly obfuscates and dirties code to have
>> declarations mixed in with executable statements;
>> ...
>
> I disagree. I prefer declarations to have a reasonably narrow scope,
> and I sometimes introduce a block for the purpose of adding a local
> declaration.
>

I also like keeping functions small enough that there would be no reason for
there to be a scope more local than the function level...


> --
> Keith Thompson (The_Other_Keith) kst-u@mib.org
> <http://www.ghoti.net/~kst>
> Nokia
> "We must do something. This is something. Therefore, we must do this."
> -- Antony Jay and Jonathan Lynn, "Yes Minister"


== 10 of 16 ==
Date: Thurs, Jul 30 2009 3:40 pm
From: "BGB / cr88192"

"BGB / cr88192" <cr88192@hotmail.com> wrote in message
news:h4t6p7$rm0$1@news.albasani.net...
>
> "Keith Thompson" <kst-u@mib.org> wrote in message
> news:lnvdl9ygr6.fsf@nuthaus.mib.org...
>> "BGB / cr88192" <cr88192@hotmail.com> writes:
>>> "Squeamizh" <squeamz@hotmail.com> wrote in message
>>> news:c0927f54-f774-4c28-ad22-69ae3ee4e2b6@l5g2000pra.googlegroups.com...
>>> On Jul 30, 12:34 pm, "BGB / cr88192" <cr88...@hotmail.com> wrote:
>> [...]
>>>> nesting and using "local objects" in this way, is bad practice, FWIW...
>>>> granted, some newer compilers allow it (such as GCC), and it is part of
>>>> C99,
>>>> but this does not make it a good style.
>>>>
>>>> either all declarations are done at the top of the function, or the
>>>> function
>>>> should be split.
>>>
>>> <--
>>> First, you're wrong; declaring variables local to a block is legal in
>>> c89. Secondly, you labeling something as "bad practice" is
>>> meaningless without being accompanied by some sort of explanation.
>>> WHY is it bad practice?
>>> -->
>>>
>>> AFAIK, it is not legal in C89 (after all, if it had been legal since
>>> C89, no
>>> one would need mention it becomming legal in C99...).
>>>
>>> (note: by this, I meant internal blocks, such as with a for loop or if
>>> block...).
>>>
>>> it was only "made" legal in C99, and was informally legal in many
>>> compilers
>>> (much like the "//" comment syntax, which has worked damn near as long
>>> as I
>>> have been using C, but was also not legal until C99...).
>>
>> You are mistaken.
>>
>> Mixing declarations and statements within a block is illegal in C90,
>> legal in C99 and C++.
>>
>> Declarations within blocks have been legal at least since K&R1; even
>> BCPL permitted them.
>>
>
> this is what I had meant...
>
> you misunderstood what I had written...
>

to clarify:
int foo()
{
int i, j, k;
...
for(i=0; i<10; i++)
...
}

this is OK, no problems...

now as for:
int foo()
{
...
for(int i=0; i<10; i++)
{
int j, k;
...
}
...
}

only valid for C++ and for C99 and newer, and supported as a language
extension to many C compilers, but not technically not legal in C89.

this would seem to be what the prior person was debating...

my use of "block" then, meant "internal blocks" or similar, not the function
as a whole...


FWIW, not all C compilers conform with C99...

== 11 of 16 ==
Date: Thurs, Jul 30 2009 4:45 pm
From: Squeamizh


On Jul 30, 3:40 pm, "BGB / cr88192" <cr88...@hotmail.com> wrote:
> to clarify:
> int foo()
> {
>     int i, j, k;
>     ...
>     for(i=0; i<10; i++)
>     ...
>
> }
>
> this is OK, no problems...
>
> now as for:
> int foo()
> {
>     ...
>     for(int i=0; i<10; i++)
>     {
>         int j, k;
>         ...
>     }
>     ...
>
> }
>
> only valid for C++ and for C99 and newer, and supported as a language
> extension to many C compilers, but not technically not legal in C89.

The fastest way to get to the bottom of this is to ask you a direct
question. Is your claim that the following code is not permissible in
C89:

int foo(void)
{
int i;
for(i=0; i<10; i++)
{
int j;

j = i;
}
}

...yes or no?


== 12 of 16 ==
Date: Thurs, Jul 30 2009 4:53 pm
From: Jerry Coffin


In article <h4t0kr$iul$1@news.albasani.net>, cr88192@hotmail.com
says...

[ ... ]

> simple solution:
> don't design API's this way...
>
> each side of the API manages its own memory, and no memory or resource
> ownership should be passed across this border.

The API in question was one for allocating memory. The rest of your
comments simply don't apply for such a thing.

[ ... ]

> the usual alternatives:
> know what you are doing;
> don't pass around resource ownership all over the place (there ARE ways to
> move data from place to place, without directly transporting resource
> ownership);
> ...
>
> virtualize the resources, and virtualize their access and transport, and
> many of these management issues either lessen or go away.

That certainly sounds good -- at least in a world where hand-waving
generalizations cure real problems.

[ ... ]

> > 1) Decades of experience has shown that while it's
> > _theoretically_ possible to get it right in C, that in the entire
> > history of C, there's probably never been even one nontrivial
> > program that didn't have at least one memory management problem.
> > For any practical purpose, that qualifies as "impossible".
> >
>
> by extension, this would be the case of C++ as well...

Not true, for the simple reason that the basis isn't true in C++.
Quite a bit of software developed in C++ doesn't appear to have any
memory management problems at all.

> after all, Java was written in part with the intent to address these sorts
> of problems, in C++...

Certainly Sun has claimed they designed Java to cure problems in C++.
A large number of the problems they cited, however, are either
obviously imaginary, or not cured by Java at all. Somebody with a
vested interest in one product saying less than complimentary things
about a (perceived) competitor hardly qualifies as proof of anything.

> > 2) The improvement is hardly "incremental" -- in typical cases, it's
> > a lot _more_ than one order of magnitude improvement.
> >
>
> as you claim...
> this claim, however, is not substantiated with any more than straw-men...

Rather the contrary -- it's substantiated with a couple of decades of
writing code myself, and looking at code other people have written.

> just because you can accuse people of using generally horrid coding
> practices, does not mean they actually do so by definition.

Oh calm down and try to deal with reality!

The basic problem being dealt with is pretty simple. In C, you run
into two problems. First of all, about the only thing C provides for
dealing with dynamic data is malloc/calloc/realloc/free. Second, it
makes it essentially impossible to centralize the use of those tools.

> "well, you use C++, that means by default you like making hugely
> tangled class heirarchies and #includ'ing your entire source tree
> into a single file...", "don't deny it, we KNOW this is how people
> write C++...", "that and with all the operator overloading on damn
> near every class, and use of recursive templates...", ...
>
> see the point?...

If "the point" is that you realize you've lost the argument based on
facts, and prefer to spout nonsense rather than admit you're wrong,
then yes. If there was supposed to be another point, you've failed to
make it.

> > 3) The number of scenarios where it provides a nontrivial improvement
> > is extremely large -- I'd say well over 90% of all typical code can
> > use RAII to manage the lifetime of most objects.
> >
>
> but, is this actually necessary?...
> or is it, rather, the case that one CAN get by without using it?...

In theory, you can also get by on simply being the world's greatest
genius, and always doing things perfectly with no help from the
language at all.

In reality, experience has shown that that approach just doesn't
work.

[ ... ]

> partial reason:
> because, at its core, C++ is based on C, and, essentially, manages the
> resources in the same basic ways, and with the same basic issues.

I've already pointed out that this is just plain wrong. Repeating
your falsehood is NOT going to make it true.

[ ... ]

> a task which can be done in one can, thus, be done in the other,
> typically with only a modest difference in overall code size.

Oh what a load of horse hockey! Let's look at a truly trivial
example:

#include <string>
#include <set>
#include <algorithm>
#include <iterator>
#include <iostream>

int main() {
std::string line;
std::set<std::string> lines;

while (std::getline(std::cin, line))
lines.insert(line);
std::copy(lines.begin(), lines.end(),
std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}

The problem statement is pretty simple: you need to read lines from
standard input, and then write the unique lines in sorted order to
standard output. The maximum line length and maximum number of lines
should be limited only by available memory.

Now, as shown above in C++, even if we include blank lines,
#include's, and so on, it's trivial to do that in less than 20 lines.

C just doesn't provide the tools to make this trivial at all. For
example, here's code just to read in a string of arbitrary size:

char *getstring(void) {
int ch;
size_t i;
static size_t bufsize = 0;
static char *buffer = NULL;

for (i = 0;((ch=getchar())!= EOF) && (ch!='\n')&&(ch!='\r'); ++i)
{
if (i + 1 > bufsize)
{
/* If buffer is full, resize it. */
char *temp = realloc(buffer, bufsize+BLOCKSIZ);
if (NULL==temp) {
puts("\agetstrng() - Insufficient memory");
/* Add terminator to partial string */
buffer[i] = '\0';
return buffer;
}
buffer = temp;
bufsize += BLOCKSIZ;
}
buffer[i] = (char)ch;
}
buffer[i] = '\0'; /* Tack on a null-terminator. */
return buffer;
}

All by itself, this is larger and more complex than the complete
program in C++. Then we need to write another very similar routine to
manage a dynamic array to hold the lines we read. Alternatively, we
could do like the C++ code does, and use a balanced tree of some sort
(R-B tree, AVL tree, etc.), but that's going to expand the code a LOT
more -- plan on around 100 lines of fairly tricky code just to do an
insertion in a balanced tree. As yet another alternative, you could
use a tree that doesn't attempt to keep itself balanced -- this will
keep the code a lot simpler at the expense of worst case performance
being roughly O(n*n) instead of O(n*log(n)).

> the actual differences then, are not significant, rather, they are modest...

See the example above -- the difference qualifies as at least
significant, and probably closer to "dramatic". Looked at from
another perspective, it's simply average -- about what we can expect
to see in a typical case.

> as I see it, about the MOST fundamental difference, is that C++ has built in
> exception handling...

It looks to me like you haven't seen enough about the subject mater
for your opinion on it to mean a whole lot. It's certainly true that
exception handling makes a difference (and that there's a very nice
synergy between exception handling and RAII) but it still seems to me
that you're missing most of the picture here.

> or, oh wait, maybe this whole time you have benn talking about Java or
> C#?...

Not a chance. While I've used both, I'm not particularly enthused
about either one, and I while I think completely manual memory
management is a poor idea, I don't think the GC in C# or (especially)
Java is all that much of an improvement.

At the risk of being accused of inappropriate similes again, I'd
liken memory management to being a bit like mowing a lawn.

In C, it's a bit like being forced to mow the lawn by crawling around
on your hands and knees, cutting each individual blade of grass to
the correct height with a hand clipper. It works all right for a
little while, and certainly gives you all the control you could
possibly want, but it's tedious and error prone at very best.

In C# or Java, they've gone to the opposite extreme -- a state-run
landscaping service that's going to landscape your yard as they see
fit, mow it exactly the way they want to as often (or rarely) as they
want to, leave you with no ability to do any of it, or even have the
slightest influence of what will be done.

C++ lets you hire a lawn mowing service (garbage collector) if you
want, or you can use your own lawn mower (RAII), or in those places
you really want to, you can clip individual blades by hand (manual
management).

[ ... ]

> not the same term, but this has been your apparent general position
> throughout this thread.

IOW, you're quite explicitly putting words in my mouth instead of
even making any real attempt at honesty at all.

--
Later,
Jerry.


== 13 of 16 ==
Date: Thurs, Jul 30 2009 5:03 pm
From: jacob navia


Jerry Coffin wrote:
>
> The basic problem being dealt with is pretty simple. In C, you run
> into two problems. First of all, about the only thing C provides for
> dealing with dynamic data is malloc/calloc/realloc/free. Second, it
> makes it essentially impossible to centralize the use of those tools.
>

The lcc-win C compiler provides a GC. This allows for much easier
programming what memory management is concerned. You just
replace malloc by GC_malloc, and forget about free

:-)


== 14 of 16 ==
Date: Thurs, Jul 30 2009 5:29 pm
From: Jerry Coffin


In article <fbe99bda-74a8-40ee-a697-608812365516
@v36g2000yqv.googlegroups.com>, coal@mailvault.com says...

[ ... ]

> I agree with the above except for the 90% figure. I don't
> have anything to go on other than my opinion that RAII is
> not as helpful in servers as in programs that run once and
> exit. In run once programs I wouldn't argue with that
> figure, but I don't consider those programs to be as
> interesting as servers.

Hmm...most of what I write isn't exactly servers, but most of it
isn't like a filter that just processes some input to the end, then
exits either. My longest running example would be a controller for a
sewage treatment plant -- so far it's been booted twice in something
like 18 years: once when it was new, and once when we had severe
enough rain that some of the equipment (especially some dams it uses
to control flows) were destroyed and had to be rebuilt.

--
Later,
Jerry.


== 15 of 16 ==
Date: Thurs, Jul 30 2009 5:35 pm
From: Jerry Coffin


In article <h4tcbv$apv$1@aioe.org>, jacob@nospam.org says...
>
> Jerry Coffin wrote:
> >
> > The basic problem being dealt with is pretty simple. In C, you run
> > into two problems. First of all, about the only thing C provides for
> > dealing with dynamic data is malloc/calloc/realloc/free. Second, it
> > makes it essentially impossible to centralize the use of those tools.
> >
>
> The lcc-win C compiler provides a GC. This allows for much easier
> programming what memory management is concerned. You just
> replace malloc by GC_malloc, and forget about free

In theory, almost any C compiler could include a GC -- but most
don't, and portable code certainly can't count on it. Of course, the
same is true in C++.

More less orthogonally, while GC works quite nicely for memory (at
least in some situations) it does nothing at all for managing other
resources (file handles, handles to GUI stuff, etc.)

--
Later,
Jerry.


== 16 of 16 ==
Date: Thurs, Jul 30 2009 5:39 pm
From: Keith Thompson


"BGB / cr88192" <cr88192@hotmail.com> writes:
> "Keith Thompson" <kst-u@mib.org> wrote in message
> news:lnvdl9ygr6.fsf@nuthaus.mib.org...
>> "BGB / cr88192" <cr88192@hotmail.com> writes:
>>> "Squeamizh" <squeamz@hotmail.com> wrote in message
>>> news:c0927f54-f774-4c28-ad22-69ae3ee4e2b6@l5g2000pra.googlegroups.com...
>>> On Jul 30, 12:34 pm, "BGB / cr88192" <cr88...@hotmail.com> wrote:
>> [...]
>>>> nesting and using "local objects" in this way, is bad practice, FWIW...
>>>> granted, some newer compilers allow it (such as GCC), and it is part of
>>>> C99,
>>>> but this does not make it a good style.
>>>>
>>>> either all declarations are done at the top of the function, or the
>>>> function
>>>> should be split.
>>>
>>> <--
>>> First, you're wrong; declaring variables local to a block is legal in
>>> c89. Secondly, you labeling something as "bad practice" is
>>> meaningless without being accompanied by some sort of explanation.
>>> WHY is it bad practice?
>>> -->
>>>
>>> AFAIK, it is not legal in C89 (after all, if it had been legal since C89,
>>> no
>>> one would need mention it becomming legal in C99...).
>>>
>>> (note: by this, I meant internal blocks, such as with a for loop or if
>>> block...).
>>>
>>> it was only "made" legal in C99, and was informally legal in many
>>> compilers
>>> (much like the "//" comment syntax, which has worked damn near as long as
>>> I
>>> have been using C, but was also not legal until C99...).
>>
>> You are mistaken.
>>
>> Mixing declarations and statements within a block is illegal in C90,
>> legal in C99 and C++.
>>
>> Declarations within blocks have been legal at least since K&R1; even
>> BCPL permitted them.
>>
>
> this is what I had meant...

Ok, I'll take your word for that.

> you misunderstood what I had written...

No, I understood what you wrote. Apparently what you wrote didn't
match what you meant.

Re-reading the quoted text, it still appears that you were claiming,
quite clearly, that C89 doesn't allow declarations within nested
blocks. In fact, it does.

[...]

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

==============================================================================
TOPIC: Alternatives to C: ObjectPascal, Eiffel, Ada or Modula-3?
http://groups.google.com/group/comp.lang.c++/t/40783f7f814400c9?hl=en
==============================================================================

== 1 of 3 ==
Date: Thurs, Jul 30 2009 2:44 pm
From: Isaac Gouy


On Jul 30, 12:38 pm, fft1976 <fft1...@gmail.com> wrote:
> On Jul 30, 10:59 am, Isaac Gouy <igo...@yahoo.com> wrote:
>
> > "shaky results"? Didn't you confirm those results yourself?
>
> Perhaps he is referring to I/O being the bottleneck. I have to say, if
> this is true, it undermines the usefulness of the benchmark to me.
>
> Take it easy.


His measurements suggest about 1.7s of a 6s difference might be
accounted for by slow Text_IO in programs that write 245MB.

The benchmarks game measurements are made with stdout redirected to /
dev/null - we don't know if that was also the case for the
measurements reported by Georg Bauhaus.


== 2 of 3 ==
Date: Thurs, Jul 30 2009 3:14 pm
From: Paul Rubin


Isaac Gouy <igouy2@yahoo.com> writes:
> His measurements suggest about 1.7s of a 6s difference might be
> accounted for by slow Text_IO in programs that write 245MB.
>
> The benchmarks game measurements are made with stdout redirected to /
> dev/null - we don't know if that was also the case for the
> measurements reported by Georg Bauhaus.

If Text_IO is slow, it could be that it burns a lot of cpu doing
format conversions, or maybe it uses less buffering than stdio and
therefore does more system calls. Redirecting to /dev/null wouldn't
make any difference to either of those.


== 3 of 3 ==
Date: Thurs, Jul 30 2009 5:48 pm
From: Oxide Scrubber


Jon Harrop wrote:
> fft1976 wrote:
>> On Jul 29, 12:24 pm, Jon Harrop <j...@ffconsultancy.com> wrote:
>>>> This is fanboy fantasy, not reality.
>>> Yes. Clojure has some nice features but its most serious deficiencies are
>>> inherited from the JVM and there is nothing Clojure can do about it, e.g.
>>> value types and TCO.
>> Not as far as speed is concerned, in practice. If you give up 1.5x
>> speed by going from C++ to Java, and 5-10 by going from Java to
>> Clojure [1], than the latter is much more relevant.
>
> Lack of value types can cost you a lot more than 1.5x though. Try writing an
> FFT over boxed complexes and Java and compare with unboxed in C99, for
> example.

Clojure has TCO; you just have to make your use of it explicit (and then
the compiler alerts you if it's not really in tail position).

I'm not sure what you mean by "value types". If you mean immutable types
with value-equality semantics remaining consistent over time, then
Clojure is chock full of them, even its collection types can be used as
value types, so as keys in maps for instance.

If you mean non-pointer types, Clojure has access to the full range of
Java non-pointer types: boolean, byte, short, int, long, float, double,
and char.

It can't currently pass them across function call boundaries without
boxing and unboxing, but you can work around that using definline or a
macro.

> This goes way beyond number crunching though. Lots of applications benefit
> enormously from value types. They are used extensively in the .NET
> framework.

The JVM has several non-pointer types too, and does not have the
Microsoft taint.

==============================================================================
TOPIC: Printing the last item of a structure twice
http://groups.google.com/group/comp.lang.c++/t/9fd75392aae26667?hl=en
==============================================================================

== 1 of 4 ==
Date: Thurs, Jul 30 2009 3:11 pm
From: Rafael Anschau


Hi,

The following program reads a structure into a file 3 times, but when
I tell
it to print them all, it prints the last one twice. I apreciate any
help on what
am I doing to cause this.

Thank you,

Rafael

#include <string.h>
#include <string>
#include<iostream>

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
char nf[]="1.tst";
string str="Hello world";
FILE *fp;


if ((fp=fopen(nf,"w+"))==NULL) {
std::cout<<"Erro nao abriu";
int a;
cin>>a;
exit(1);
}
typedef struct endereco {
string rua;
int n;


} ender;

ender meu,teu;

int i;

rewind(fp);
for(i=0;i<3;i++) {
cout<<"Nome da rua:\n";
cin>>meu.rua;
cout<<"Numero do ap:\n";
cin>>meu.n;

fwrite(&meu,sizeof(ender),1,fp);

}

cout<<"Listando\n";

rewind(fp);
while(!feof(fp)) {
fread(&teu,sizeof(ender),1,fp);
cout<<teu.rua<<"\n";
cout<<teu.n<<"\n";
}

int a;
cin>>a;

}


== 2 of 4 ==
Date: Thurs, Jul 30 2009 4:54 pm
From: Jonathan Lee


On Jul 30, 6:11 pm, Rafael Anschau <rafael.ansc...@gmail.com> wrote:
> The following program reads a structure into a file 3 times

Yes, but that's not actually what you want it to do. You want it to
write the _value_ of rua, and the int. But that's not what it's doing.

If you check sizeof(string) you will find that it is always the same
regardless of the contents. On my machine, that's 4 bytes, probably
because it is only a wrapper around a pointer.

So when you do this:

fwrite(&meu, sizeof(ender), 1, fp);

you are only writing a pointer ("rua") and the int ("n"). You're not
writing the string that "rua" is pointing to.

Depending on your inputs, that pointer stored by "rua" might not
actually change. So you write out the same pointer 3 times. Then you
read that same pointer back 3 times and they all point to the same
thing: the last string you've read from the keyboard.

You really need a way to serialize the object (hint: Google "serialize
C++") and a way to recover it. Doing it the way you have is a bad idea
-- as you've seen it doesn't work.

--Jonathan


== 3 of 4 ==
Date: Thurs, Jul 30 2009 5:03 pm
From: Rafael Anschau


Actually the problem was I had to refine my definition for feof: It
only returns trues after it tries to pass eof, not when it reaches it.

But thanks anyway,

Rafael


On Jul 30, 8:54 pm, Jonathan Lee <cho...@shaw.ca> wrote:
> On Jul 30, 6:11 pm, Rafael Anschau <rafael.ansc...@gmail.com> wrote:
>
> > The following program reads a structure into a file 3 times
>
> Yes, but that's not actually what you want it to do. You want it to
> write the _value_ of rua, and the int. But that's not what it's doing.
>
> If you check sizeof(string) you will find that it is always the same
> regardless of the contents. On my machine, that's 4 bytes, probably
> because it is only a wrapper around a pointer.
>
> So when you do this:
>
>    fwrite(&meu, sizeof(ender), 1, fp);
>
> you are only writing a pointer ("rua") and the int ("n"). You're not
> writing the string that "rua" is pointing to.
>
> Depending on your inputs, that pointer stored by "rua" might not
> actually change. So you write out the same pointer 3 times. Then you
> read that same pointer back 3 times and they all point to the same
> thing: the last string you've read from the keyboard.
>
> You really need a way to serialize the object (hint: Google "serialize
> C++") and a way to recover it. Doing it the way you have is a bad idea
> -- as you've seen it doesn't work.
>
> --Jonathan

== 4 of 4 ==
Date: Thurs, Jul 30 2009 5:06 pm
From: Jerry Coffin


In article <6ff1c26e-5bf9-4092-86aa-d021f3e310e3
@h30g2000vbr.googlegroups.com>, rafael.anschau@gmail.com says...

[ ... ]

> while(!feof(fp)) {

Your problem is right here. The problem is that eof on a stream isn't
detected until AFTER you attempt a read and you're at the end of the
end of the file, and the attempted read fails. When the read fails at
the end of the file, what was previously read will still be there,
but you won't have detected the end of the file yet, so you'll
process it again. Then the code above will detect that the previous
read failed and quit trying to read any more.

--
Later,
Jerry.

==============================================================================
TOPIC: How to split this string correctly?
http://groups.google.com/group/comp.lang.c++/t/1845370483de2cfa?hl=en
==============================================================================

== 1 of 1 ==
Date: Thurs, Jul 30 2009 4:01 pm
From: "barcaroller"

"Digital Puer" <digital_puer@hotmail.com> wrote

> Is there a way to do this splitting? I am on Linux and can use
> Boost libraries (I know there is some regex library, but I have never
> used it).

You have a few options to split a string based on specific tokens and/or
separators. In plain C you can use strcmp() and/or strtok() to write your
own routine.

In C++ you can can use:
- strcmp() and/or strtok() again
- std::string(); look at find() and related members
- boost::algorithm::string
- boost::tokenizer
- boost::regex


==============================================================================
TOPIC: question on vector<char>::difference_type
http://groups.google.com/group/comp.lang.c++/t/0887bb3c0dd6545e?hl=en
==============================================================================

== 1 of 1 ==
Date: Thurs, Jul 30 2009 5:26 pm
From: Victor Bazarov


subramanian100in@yahoo.com, India wrote:
> I wrote the following program for learning purpose only.
> [..]
> Why is the difference_type not large enough to hold the distance
> between any two iterators ?

That's a good question you should most likely be asking the implementors
of the standard library you're using. The quantities and the types are
implementation-defined. Some implementors *could* decide to use a
larger signed type for 'difference_type' just to satisfy that
requirement. Apparently in the particular implementation you use, they
didn't. Why?... How should we know?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


==============================================================================

You received this message because you are subscribed to the Google Groups "comp.lang.c++"
group.

To post to this group, visit http://groups.google.com/group/comp.lang.c++?hl=en

To unsubscribe from this group, send email to comp.lang.c+++unsubscribe@googlegroups.com

To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.c++/subscribe?hl=en

To report abuse, send email explaining the problem to abuse@googlegroups.com

==============================================================================
Google Groups: http://groups.google.com/?hl=en

No comments: