Monday, April 26, 2021

Digest for comp.lang.c++@googlegroups.com - 25 updates in 2 topics

Robert Latest <boblatest@yahoo.com>: Apr 26 10:41AM

["Followup-To:" header set to comp.lang.c.]
Juha Nieminen wrote:
> Not comparable because my entire point was about how laborious and
> error-prone it is to handle *dynamically allocated* (and length-changing)
> strings.
All coding is laborious and error prone if you're both lazy and sloppy.
 
--
robert
jacobnavia <jacob@jacob.remcomp.fr>: Apr 26 01:20PM +0200

Le 26/04/2021 à 11:57, Juha Nieminen a écrit :
> Can you show me a C++ program from 2000 that doesn't?
 
Breaking changes in C++ 2011
 
1) the introduction of explicit operator bool() in the standard library,
replacing old instances of operator void*().
 
2) #define u8 "abc"
const char *s = u8"def"; // Previously "abcdef", now "def"
 
3) #define _x "there"
"hello"_x // now a user-defined-string-literal. Previously, expanded _x
 
4) New keywords: alignas, alignof, char16_t, char32_t, constexpr,
decltype, noexcept, nullptr, static_assert, and thread_local
 
5) Certain integer literals larger than can be represented by long could
change from an unsigned integer type to signed long long.
 
6) Valid C++ 2003 code that uses integer division rounds the result
toward 0 or toward negative infinity, whereas C++0x always rounds the
result toward 0.
 
7) struct A { private: A(); };
struct B : A { };
int main() { sizeof B(); /* valid in C++03, invalid in C++0x */ }
Such sizeof tricks have been used by some SFINAE, and needs to be
changed now :)
 
8) banning of narrowing conversions during aggregate initialization:
 
int a = {1.0; }; // error
 
9) Implicit move breaks C++ 2003 code. The long explanation why is to be
found at:
http://web.archive.org/web/20140110035813/http://cpp-next.com/archive/2010/10/implicit-move-must-go/
 
10) I remember that in an older version of C++ the templates arguments
are checked and must be defined at the point of expansion, the new
version of the language needs that they are defined at the point of
definition. Or something like that. I earned two weeks consulting to
update a huge codebase. Actually I love C++ :-)
 
And I will stop here... You apparently have no idea how c++ has changed
over the years, with each new version incompatible in some point with
the older one.
 
Only in C you can still use the code of 50 years ago.
Juha Nieminen <nospam@thanks.invalid>: Apr 26 01:17PM

> Le 26/04/2021 à 11:57, Juha Nieminen a écrit :
>> Can you show me a C++ program from 2000 that doesn't?
 
> Breaking changes in C++ 2011
 
I think all the major C++ compilers support C++98 mode.
 
And it's not like C hasn't change either. This compiles as C89 but not
as C99:
 
#include <stdio.h>
 
int main()
{
int restrict = 1, inline = 2;
printf("%i %i\n", restrict, inline);
return 0;
}
Bonita Montero <Bonita.Montero@gmail.com>: Apr 26 06:04PM +0200

Use C++ - much less code, more maintainable and more readable code
if you use it properly. Sth. like malloc() f.e. is really disgusting
when compared to using a vector<>.
Guillaume <message@bottle.org>: Apr 26 06:48PM +0200

Le 26/04/2021 à 07:22, Juha Nieminen a écrit :
 
> The main point is that malloc()'ing something and not free()'ing it is
> bad practice. Not only does it teach you bad habits, it teaches other
> people reading the code this same bad habit.
Whereas I personally agree with this, I reckon there are different ways
of seeing it, some in favor of actually doing exactly what they did.
 
If you assume that all malloc'ed memory will be reclaimed when the
program terminates, then not explicitely freeing it in this case (where
you would be free it just before the program terminates anyway) actually
makes sense and shows you know what you're doing. One can even argue
that useless statements are just code pollution.
 
Now regarding the above assumption, whereas it's reasonable on any
"decent" OS, including the one(s) the authors were targetting at the
time they wrote this piece of code, I could not find any explicit
mention of this in the C standard regarding memory allocation - unless
of course I missed it, which means the hosted environment is not
required to reclaim allocated memory upon program termination. It's
implementation-defined, thus the quoted program is, by definition,
non-portable. Which is one good reason to claim it's bad practice indeed.
 
As to another reason why I would not do this: code reusability. I tend
to write code so that it can be reused. The way it's implemented in the
quoted program, it's just not reusable if you wanted to make a "text
editor" component out of it and reuse it in a completely different program.
jacobnavia <jacob@jacob.remcomp.fr>: Apr 26 07:53PM +0200

Le 26/04/2021 à 15:17, Juha Nieminen a écrit :
> printf("%i %i\n", restrict, inline);
> return 0;
> }
 
Yes, that is why I did NOT even mention the same problems that C++ has
(auto keyword, and MANY others, much more than C)
James Kuyper <jameskuyper@alumni.caltech.edu>: Apr 26 01:54PM -0400

On 4/26/21 1:22 AM, Juha Nieminen wrote:
...
> people reading the code this same bad habit. This is especially
> egregious in code that's being used for didactic purposes out there,
> for thousands and thousands of students to see.
 
There's a fundamental problem with arguments of that type: if the person
you're arguing with doesn't already accept that it is a bad practice,
he's not going to have any problems with teaching others to adopt it. If
he does accept that it's a bad practice, he'll stop using it for that
reason alone, and will then automatically become a good example for
others to follow. So bringing up the effects on other people doesn't
actually do anything useful for your argument.
David Brown <david.brown@hesbynett.no>: Apr 26 08:34PM +0200

On 26/04/2021 19:53, jacobnavia wrote:
>> }
 
> Yes, that is why I did NOT even mention the same problems that C++ has
> (auto keyword, and MANY others, much more than C)
 
Yes, you did - your number 4 item was a list of new keywords whose only
backwards compatibility issue is if they happen to be used as
identifiers. (There are more than in C99 - no arguments there. I'd not
expect significantly more conflicts, however.)
 
There are a few cases where it might be reasonable to think /real/ code
written for C++03 would no longer be valid (or have the same effect)
when compiled as C++11 or newer. But they would be rare. Listing silly
things like defining "u8" as a macro of a string and using it for string
concatenation (without a space) is just petty. It is not a realistic
concern, nor an example of what Juha asked for - it is just FUD, and a
sign of desperation. You prefer C to C++ - that's fine, everyone has
their preferences. But if you don't have real reasons, there's no need
to invent unrealistic reasons.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Apr 26 09:37PM +0100

> written 50 years ago of just 1700 lines. It compiles and runs 50 years
> later. Please show me a complex program in C++ from 2000 that compiles
> unmodified and runs today.
 
The posted code can't be 50 years old. ed is 50 years old, but the
original was not written in C (there was no C in 1971).
 
The version posted uses void and function prototypes so it dates from
the time C was first being standardised. A comment says it has been
slightly modified. It would be nice to know if that was necessary to
get it to compile, and if so, what the modification was.
 
--
Ben.
jacobnavia <jacob@jacob.remcomp.fr>: Apr 26 10:48PM +0200

Le 26/04/2021 à 22:37, Ben Bacarisse a écrit :
>> unmodified and runs today.
 
> The posted code can't be 50 years old. ed is 50 years old, but the
> original was not written in C (there was no C in 1971).
 
OK, granted
 
> the time C was first being standardised. A comment says it has been
> slightly modified. It would be nice to know if that was necessary to
> get it to compile, and if so, what the modification was.
 
I modifiedit to get rid of warnings of gcc, by changing char * into
unsigned char *. Not a big deal. You can download the original from the
URL I included
jacobnavia <jacob@jacob.remcomp.fr>: Apr 26 10:49PM +0200

Le 26/04/2021 à 20:34, David Brown a écrit :
> sign of desperation. You prefer C to C++ - that's fine, everyone has
> their preferences. But if you don't have real reasons, there's no need
> to invent unrealistic reasons.
 
Sure sure, I am desperate. But you ignored the problem with templates...
and many others I mentioned
Ben Bacarisse <ben.usenet@bsb.me.uk>: Apr 26 10:04PM +0100


> 2) #define u8 "abc"
> const char *s = u8"def"; // Previously "abcdef", now "def"
 
C has the same breaking change, but, just as with C++, you can usually
ask the compiler to use an older standard.
 
> Only in C you can still use the code of 50 years ago.
 
There was no C code 50 years ago. This is a bit of a quibble since
there was C code we'd just about recognise in about 1973 or 4, but some
of it would fool even gcc today. The biggest change was the great =<op>
to <op>= switch. This silently changed the meaning of a lot of code.
 
--
Ben.
scott@slp53.sl.home (Scott Lurndal): Apr 26 09:53PM

>> unmodified and runs today.
 
>The posted code can't be 50 years old. ed is 50 years old, but the
>original was not written in C (there was no C in 1971).
 
ed first appeared in V2. ed2.s and ed3.s
 
https://minnie.tuhs.org/cgi-bin/utree.pl?file=V2/cmd/ed2.s
 
ed.c first appeared in V6 (1975).
 
https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/source/s1/ed.c
MrSpook_gbzt63zc@83jpfr9ry9f55a.tv: Apr 26 10:22AM

On Mon, 26 Apr 2021 09:37:21 +0000 (UTC)
>> Queues. You can implement them using arrays but that would be very
>inefficient.
 
>std::deque doesn't use linked lists, and I don't think it's very inefficient.
 
It would seem it uses a combination of a tree structure (which is a type
of list) and fixed size array chunks.
 
https://stackoverflow.com/questions/6292332/what-really-is-a-deque-in-stl
 
So yes, obviously fixed sized arrays are efficient but I suspect the potential
memory wastage isn't something that would suit everyone. And you probably
wouldn't implement something this complex yourself in C unless it was a very
specific application.
Robert Latest <boblatest@yahoo.com>: Apr 26 10:35AM

["Followup-To:" header set to comp.lang.c.]
Juha Nieminen wrote:
>> Doesn't make sense.
 
> Are you telling be that every single time you create a struct in a C program
> you always write a "constructor" and "destructor" for it,
 
Of course not.
 
> just in case that some time in the future they might start requiring them?
 
No. Only if the data structure requires it, as is typical with nested,
dynamically allocated structs. Then of course it requires only a few extra
lines of code per struct type. If your struct is used for any non-trivial
amount of work you'll need some init code anyway.
 
> Well, even if you actually do, my point stands: In C++ you don't need to do
> that.
 
Then why don't you use C++ if thinking about memory management bothers you so
much?
 
--
robert
Bo Persson <bo@bo-persson.se>: Apr 26 01:05PM +0200


>> std::deque doesn't use linked lists, and I don't think it's very inefficient.
 
> It would seem it uses a combination of a tree structure (which is a type
> of list) and fixed size array chunks.
 
The internal structure is not a list (or a tree), but an array of
pointers to the chunks. This array *will* have to be reallocated
occationally, but only by copying the set of pointers, not by moving all
the data stored in the chunks.
 
 
David Brown <david.brown@hesbynett.no>: Apr 26 01:10PM +0200

> memory wastage isn't something that would suit everyone. And you probably
> wouldn't implement something this complex yourself in C unless it was a very
> specific application.
 
In situations where you might worry about the memory wastage of a
fixed-size array of pointers, you are most likely dealing with a
small-system resource constrained embedded system. And in that case,
you /definitely/ want a fixed size array, not dynamic memory - because
/knowing/ that your system has enough memory is vastly more important
than minimising the memory usage. (You wouldn't use a C++ std::deque in
such cases, of course - you'd prefer a std::array.)
Paavo Helde <myfirstname@osa.pri.ee>: Apr 26 02:38PM +0300


> Queues. You can implement them using arrays but that would be very inefficient.
> Obviously in C++ there are already queue containers, but in C you'd use
> a linked list.
 
In C++ the container to use for queues is std::deque. In C one does not
use it because it would be too tedious and error-prone to code it. So in
C one uses a linked list instead which is relatively easy to code (but
still pretty error prone).
 
So in C++ we have a built-in superior data structure which does not need
developing and is easy to use. This data structure is not used in C
because it's too hard to develop and too hard to use. How this would
prove anything in favor of C is beyond my imagination.
Juha Nieminen <nospam@thanks.invalid>: Apr 26 01:08PM


>> Are you telling be that every single time you create a struct in a C program
>> you always write a "constructor" and "destructor" for it,
 
> Of course not.
 
That's exactly my point:
 
Suppose you have a huge amount of code, with lots and lots of structs, structs
as members of other structs, and a lot of code that uses those structs.
 
Then one day you decide to add a dynamically allocated array (such as a
dynamically allocated string) to one of the structs, which is used in
lots of other structs, which themselves are used in other structs, and
so on...
 
Because of a chance in this one struct, suddenly lots of other structs
"inherit" its need for manual construction and destruction, and tons of
code that uses those other structs need to be refactored to now call the
constructors and destructors of all the structs that now require it.
All because of this one struct.
 
In C++, you don't have to. You just add the dynamic data structure to
that one struct, and you're done. No need to modify anything else.
 
>> that.
 
> Then why don't you use C++ if thinking about memory management bothers you so
> much?
 
That's exactly what I do, whenever I can.
Richard Damon <Richard@Damon-Family.org>: Apr 26 09:30AM -0400

On 4/26/21 9:08 AM, Juha Nieminen wrote:
 
>> Then why don't you use C++ if thinking about memory management bothers you so
>> much?
 
> That's exactly what I do, whenever I can.
 
Yes, in C if you make that sort of change, you need to change a lot of code.
 
That is also, if you really think about it, a major breaking change in
the definition of the struct.
 
BECAUSE in C, you need to manual handle allocation, this is a breaking
API change to a structure from DEFINED to not need management, to
needing management. In C, you need to think ahead and ask if you can
conceive of a need to manage the life of the structure, and if so add
explicit create/destroy methods, even if for now, they do nothing. (You
can make them in-liene no-ops so can be no cost.
 
Yes, that is one of the advantages of C++, that you can easily change
this as C++ will automatically make this change for you. It also can be
seen as a weakness. It can be easy to make an apparently innocent
looking change that affects the performance of wide swathes of code as
that code get replicated everywhere.
MrSpook_mD_r@g72w8ixztm106rprqnby.tv: Apr 26 01:49PM

On Mon, 26 Apr 2021 14:38:08 +0300
>developing and is easy to use. This data structure is not used in C
>because it's too hard to develop and too hard to use. How this would
>prove anything in favor of C is beyond my imagination.
 
I never said it does. We were discussing interview questions for C.
Robert Latest <boblatest@yahoo.com>: Apr 26 02:15PM

["Followup-To:" header set to comp.lang.c.]
Juha Nieminen wrote:
 
> Suppose you have a huge amount of code, with lots and lots of structs,
> structs as members of other structs, and a lot of code that uses those
> structs.
 
In other words, a mess.
 
> Then one day you decide to add a dynamically allocated array (such as a
> dynamically allocated string) to one of the structs, which is used in lots of
> other structs, which themselves are used in other structs, and so on...
 
I get your point. BTW I take "lots of structs" to mean "lots of struct types,"
not "lots of instances"
 
> that uses those other structs need to be refactored to now call the
> constructors and destructors of all the structs that now require it. All
> because of this one struct.
 
Correct. At fault is not the language, nor the lack of a garbage collector, but
an ill-designed and unmaintainable pile of code which is badly in need of
refactoring anyway. Are you speaking of a real-life example? Dozens of
different struct types that all include one another and none of which
(originally) have dynamically allocated members?
 
--
robert
James Kuyper <jameskuyper@alumni.caltech.edu>: Apr 26 10:25AM -0400

On 4/23/21 7:58 AM, wij wrote:
...
> ... You cannot use memcpy/memmove in 'pure' C++.
 
You can use them in well-formed C++ code. "well-formed" is a term
defined precisely by the C++ standard. "pure C++" not a term defined by
the standard. I suppose that it may be defined by you - but if so, the
truth of your statement depends upon how you define that term. The
importance of your statement also depends upon that definition. I can't
come up with a plausible definition for "pure C++" that makes your
statement both true and important. Could you provide one?
wij <wyniijj@gmail.com>: Apr 26 12:07PM -0700

> importance of your statement also depends upon that definition. I can't
> come up with a plausible definition for "pure C++" that makes your
> statement both true and important. Could you provide one?
 
Forget about those snippet phrases that easily mislead occasional readers.
My mind was all about the development of C++ from its initial ideal and implement
to the real effect practiced and evaluated from the real world.
Obviously, I know little about the standard and you also understand I was not
referring to the standard.
 
The "slogan" of C++ started from system programming, changed latter to generic
programming, and settled down to multi-paradigm language.
Then, "my problem" is the concept of multi-paradigm and C++ standard practiced
by usual programmers contradict each other if C++ standard library dictates its
usage only a bit more. Other practices/implements, like mine (or Qt,..), are
easily classified as "non-standard" (multi-paradigm?).
Another one is about optimization. Procedural language (informal term) and
optimization, these two are also contraditory concepts. C++ stresses a lot about
optimization.
 
I guess all these things emerge from "No, C is not a simple language" we do
not really want to talk about. I may have written many seemingly unrelated
words, but to ruminate myself and for others who can understand.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Apr 26 10:16PM +0100

On Mon, 26 Apr 2021 04:55:18 +0000 (UTC)
> > proxy for the argument that C, although much smaller as a language than
> > C++, is not simpler than C++ and that C++ is easier to learn.
 
> I actually made no point about learning. My point was about usage.
 
I don't agree. Your original post was on a mission, and I can only read
the words you use. You employed as a case study that of a beginner
struggling with string manipulation. See your original post (17 Apr
2021 05:56:42 +0000). You may have picked an example not well fitting
to the point you were hoping to make, but so be it. If you were
concerned with usage not with learning, you might have been better
served by choosing a case study involving an experienced programmer.
 
For an experienced C and C++ programmer, if all you are doing is string
manipulation, then as I have already said std::string is easier to use.
You agree with me. I have also said that RAII improves the error rate
with respect to resource management as compared with C. You agree with
that too. I also said that building classes for RAII requires you to
understand the resource management issues that your beginner found
difficulty grasping.
 
My basic position that you disagreed with was that "Both languages are
difficult for beginners and require a high degree of skill to use
well". I stand by it. For code which is not performance critical the
managed languages are considerably easier to use. But no language
exempts you from the need to get your algorithms right.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: