Friday, April 23, 2021

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

Juha Nieminen <nospam@thanks.invalid>: Apr 23 07:12AM

> would be "Write some code to create and use a linked list". The number of
> people who didn't even know where to start never mind write working code
> was quite worrying.
 
Did you score highly if anybody would start explaining the difficulty of
creating a generic linked list in C, and asking all kinds of questions
on what exactly the requirements are for the implementation?
 
I would immediately ask "a linked list containing what kind of nodes?"
Should it be a generic type of linked list where the calling code gets
to decide what the elements contain? Or should it be just a "hard-coded"
linked list where the content is predetermined, for one particular specific
use? If it should be generic, how should the programmer be able to specify
the contents of the nodes? Should the linked list code support constructing
and destructing the nodes with user-provided construction and destruction
functions?
 
It would be the perfect example of how such a task would be so much easier
in C++, as the language directly provides the mechanisms for the programmer
to specify the node type, and for those nodes to be automatically
constructed and destroyed properly, without the linked list code having
to worry about it or change its interface according to such requirements.
 
Honestly, if I were in a situation where I'm programming in C (yes, I have
to do that too), and a linked list would seem to be like the best
solution to a particular problem, I would at a very minimum think a bit
about whether there would be an easier and better solution, rather than
deal with the nightmare of memory management of a linked list (with nodes
that might themselves require memory management).
Juha Nieminen <nospam@thanks.invalid>: Apr 23 07:20AM

> You are simply not
> going to get very far in C++ if you don't understand C strings.
 
The problem in this case is not understanding how C strings work, but
managing dynamically allocated (and length-changing) strings.
 
> I think I was thinking of your contributions to the thread "Why should
> a c programmer learn c++", in which as I recall you made similar
> points. But I am willing to be corrected.
 
My arguments there were essentially "you aren't really losing anything
by moving to C++ from C (in terms of features and efficiency)".
Juha Nieminen <nospam@thanks.invalid>: Apr 23 07:32AM

> If you try to use a design that would be well suited for C++, it is no
> surprise that the same design will lead to frustration if attempted with
> in C. Again, despite their name, the languages are very different.
 
The attempt to modularize, abstract away, the dynamic memory management of
strings is much better than trying to manage all that mess directly in the
code that's using those strings, by using just raw char pointers and trying
to always do the right thing in-line (such as reallocating, copying,
appending, shrinking, freeing...). It only makes sense to create helper
functions for all the needed string operations, and for those functions to
operate on a struct that contains any necessary data to manage the string
(such as its current length and its allocated capacity).
 
I can't think of a better way that makes the code simpler and easier.
 
This is *not* a case of "trying to do C++ in C". This is a case of trying
to use *modular design* in C. To use abstractions that make it much easier
and safer to manage dynamically allocated length-changing strings.
 
> all the bells and whistles of C++ - all of these are useful features,
> but they are only relevant if actually essential to the problem domain,
> otherwise they constitute extra baggage that is best not paid for.
 
I can't think of many situations where C shines over C++.
 
Perhaps some kind of minor argument could be presented about C having
the 'resrtict' keyword, which C++ lacks. Or about VLAs. But I'm not
sure those would be reason enough to choose C over C++ regardless of
the task at hand.
 
I program in both C++ and C as my job. C is usually chosen when there
are no other options (such as when programming for certain 8-bit
embedded processors). Quite often (and fortunately) when C is the only
viable opion, the hardware is so limited that dynamic memory allocation
is usually out of the question, so the C code is restricted to fully
static memory management, which is largely non-problematic and quite
straightforward. (In those 8-bit processors you usually don't even need
any dynamic memory allocation at any point.)
 
C is ok of a language to program with in such restricted situations.
Juha Nieminen <nospam@thanks.invalid>: Apr 23 07:34AM

>> to not autogenerate those functions, and to get better error messages.
 
> As you can only focus on partial sight, like the cases of string manipulations in C.
> I cannot make it more clear for you.
 
Because I complain about dynamic string manipulation in C, you can't explain
why you oppose C++ keywords like 'override' and 'delete'?
MrSpook_l0c6dv@66h4_0ccefudc0u8w.gov: Apr 23 09:14AM

On Fri, 23 Apr 2021 07:12:30 +0000 (UTC)
 
>Did you score highly if anybody would start explaining the difficulty of
>creating a generic linked list in C, and asking all kinds of questions
>on what exactly the requirements are for the implementation?
 
Back in those days you have enough time to get them to solve a few algorithmic
issues and ask a few pertinent questions then its on to the "Tell me about
yourself HR waffle". These days employers seem to think they need to give
potential employees a cut down CS degree exam, sometimes done over seperate
days. IMO if you can't tell someones coding ability in 30 mins then you
shouldn't be an interviewer.
 
>to specify the node type, and for those nodes to be automatically
>constructed and destroyed properly, without the linked list code having
>to worry about it or change its interface according to such requirements.
 
Or you could just use std::list. The point was to show that they understood
basic data structures and memory allocation.
 
>about whether there would be an easier and better solution, rather than
>deal with the nightmare of memory management of a linked list (with nodes
>that might themselves require memory management).
 
If you need a linked list you need a linked list. Using an array or hash
would be the wrong answer.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Apr 23 11:01AM +0100

On Fri, 23 Apr 2021 07:20:39 +0000 (UTC)
> > going to get very far in C++ if you don't understand C strings.
 
> The problem in this case is not understanding how C strings work, but
> managing dynamically allocated (and length-changing) strings.
 
That as well then.
 
First, if beginners are to write their own RAII classes effectively,
they need to know how dynamically allocated memory works; and secondly
beginners cannot I believe call themselves even moderately competent
until they understand RAII, as it is so fundamental in C++.
 
I would go further and say that a beginner cannot properly understand
the use of std::unique_ptr and std::shared_ptr without understanding
both dynamically allocated memory and RAII. Also, I do not believe
that either dynamically allocated memory or RAII are difficult
concepts for a beginner to understand, once object lifetime is grasped.
jacobnavia <jacob@jacob.remcomp.fr>: Apr 23 12:10PM +0200

Le 20/04/2021 à 23:07, Chris M. Thomasson a écrit :
 
 
> https://youtu.be/WJabPYimznY
 
> Or the following scene in Disney's Dragonslayer from 1981:
 
> https://youtu.be/TJRaLnLDMWg
 
Great arguments!
 
Technically sound, I am convinced now...
 
 
... that you have nothing to say
wij <wyniijj@gmail.com>: Apr 23 04:10AM -0700

On Friday, 23 April 2021 at 18:10:51 UTC+8, jacobnavia wrote:
 
> Great arguments!
 
> Technically sound, I am convinced now...
 
> ... that you have nothing to say
 
Let it burn. I like to play fire, safely.
 
This is not the exact one in my memory, but close.
https://www.youtube.com/watch?v=ajNieXqs8XE
wij <wyniijj@gmail.com>: Apr 23 04:58AM -0700

On Friday, 23 April 2021 at 15:34:26 UTC+8, Juha Nieminen wrote:
> > I cannot make it more clear for you.
> Because I complain about dynamic string manipulation in C, you can't explain
> why you oppose C++ keywords like 'override' and 'delete'?
 
I did not oppose 'override','delete' (I like it, instead). The main point is the
language design principle or ideal avoiding "invent a new feature and then
another one to disable it...". In this case I refer to C++ inheritage ideal
("object model" crap.). This principle can extend further to be not so rightful,
as many ideals are.
 
std::string provides "helper functions" to manipulate "C-string"
(precisely speaking, this was an error of 'pure' C++, we are now actually
talking about an erroneous feature of C++), does not mean C is ugly.
 
Helper functions(or macro/template) come with cost (user usually do not care,
but note that it can accumulate) and can not cover all cases. You cannot use
memcpy/memmove in 'pure' C++.
 
As to the memory allocation issue, in extreme cases (real programs will encounter),
e.g. many string objects, or one long string, one might even need to use zero-terminate
c-string directly and RAII becomes a hinder.
Paavo Helde <myfirstname@osa.pri.ee>: Apr 23 03:44PM +0300

23.04.2021 13:01 Chris Vine kirjutas:
> both dynamically allocated memory and RAII. Also, I do not believe
> that either dynamically allocated memory or RAII are difficult
> concepts for a beginner to understand, once object lifetime is grasped.
 
This is all fine and good, but missing a point that this is all not
needed for beginners for just using some strings. In C++ a string is
effectively a simple scalar value object as it should be, there are no
issues with dynamic allocation, lifetime or RAII.
 
Yes, the *implementation* of strings does use all of this, but this has
no relevance for beginners. There are tons of other things in C++ to
learn, the implementation of strings can be well postponed. It has
absolutely no importance to a beginner that a string is technically
stored as an array of bytes somewhere.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Apr 23 05:52PM +0100

On Fri, 23 Apr 2021 15:44:36 +0300
> learn, the implementation of strings can be well postponed. It has
> absolutely no importance to a beginner that a string is technically
> stored as an array of bytes somewhere.
 
Sure, but that was not my point. In the thread to which I was
replying, a beginner's struggles with string manipulation was used as a
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.
 
My view is that that is an unhelpful proxy: C++ may postpone the day
when the beginner has to expand her knowledge to include issues such as
the resource management which caused the beginner's misunderstandings
with string manipulation in C, but not by much. In my view, as I said,
"both languages are difficult for beginners and require a high degree
of skill to use well".
 
To digress, I will certainly agree that C++'s ubiquitous use of RAII
reduces the mistake count as compared with the equivalent code in C,
but I don't think that that was the point being made.
Manfred <noname@add.invalid>: Apr 23 08:35PM +0200

On 4/23/2021 9:32 AM, Juha Nieminen wrote:
> operate on a struct that contains any necessary data to manage the string
> (such as its current length and its allocated capacity).
 
> I can't think of a better way that makes the code simpler and easier.
 
These are design goals that make sense in many domains.
My point is that they /can/ be used in C as well, although, granted,
considerably more verbosely than in C++.
 
However, the way to do this in C is not how it looks you were trying to
do it from the sketches you presented:
 
> String str1 = String_with_cstr("hello");
> String str2 = str1;
 
 
> This is *not* a case of "trying to do C++ in C".
I think it is. We may agree to disagree - just my view of it.
 
This is a case of trying
> to use *modular design* in C. To use abstractions that make it much easier
> and safer to manage dynamically allocated length-changing strings.
And I don't think the proper way to use modular design in C is how you
sketched it. Again, just my perspective.
 
>> but they are only relevant if actually essential to the problem domain,
>> otherwise they constitute extra baggage that is best not paid for.
 
> I can't think of many situations where C shines over C++.
 
- Stability
- Portability
- Interoperability
- Availability
 
As I said earlier, I put performance aside because it is often
overestimated, and most of the times C and C++ are on par. Smaller
runtime footprint is maybe the most common plus of C in this respect.
 
> the 'resrtict' keyword, which C++ lacks. Or about VLAs. But I'm not
> sure those would be reason enough to choose C over C++ regardless of
> the task at hand.
 
If you look at the language syntax and semantics, then strictly speaking
for the most part C is a subset of C++. (although what of C++ is outside
C is so huge that the way the two languages are meant to be used is
substantially different)
 
The comparison would be about how much value is added by the extra
features of C++ (which is a huge amount) compared to the cost of
handling them (learn/design/maintain). Obviously this is heavily
dependent on the problem domain.
 
> straightforward. (In those 8-bit processors you usually don't even need
> any dynamic memory allocation at any point.)
 
> C is ok of a language to program with in such restricted situations.
 
I have seen successful large projects in C, mostly back end services.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Apr 23 12:37PM -0700

On 4/23/2021 3:10 AM, jacobnavia wrote:
 
> Great arguments!
 
> Technically sound, I am convinced now...
 
> ... that you have nothing to say
 
Have you ever had to deal with GC issues? I have... Unfortunately, some
people seem to think that a full blown GC is okay to use for reclaiming
memory in lock-free algorithms. It works, but can become a massive,
nasty, unpredictable bottleneck. Only then do they complain. I warned
some of them...
 
https://youtu.be/XcxKIJTb3Hg
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Apr 23 12:38PM -0700

On 4/23/2021 12:37 PM, Chris M. Thomasson wrote:
> nasty, unpredictable bottleneck. Only then do they complain. I warned
> some of them...
 
> https://youtu.be/XcxKIJTb3Hg
 
The bunny is the GC when you expose your lock-free system to high levels
of sustained load.
Andrey Tarasevich <andreytarasevich@hotmail.com>: Apr 23 12:16PM -0700

On 3/23/2021 4:22 PM, James Lothian wrote:
> Every online c++ compiler I've managed to find (presumably using gcc)
> accepts this code. So, who's right? Am I doing something stupid here?
 
Yes, it appears to be a bug in MSVC++. It appears that if you separate
the first parameter from each pack, it serves as a workaround and MSVC++
choses the proper specialization
 
template <int L1, int... L, int R1, int... R>
struct Mul<Unit<L1, L...>, Unit<R1, R...> >
{
typedef Unit<L1 + R1, L + R...> Result;
};
 
--
Best regards,
Andrey Tarasevich
MrSpook_wqqeppl@_nb0l03nl53p.tv: Apr 23 09:09AM

On Thu, 22 Apr 2021 14:16:49 -0300
>using for that std::bind, which can accept any kind of callable object
>(free functions, functors, member functions, lambdas, etc) with the
>optional plus of binding/adding extra predefined values to your callback.
 
Ugh. Obfuscated code for the sake of being clever.
Cholo Lennon <chololennon@hotmail.com>: Apr 23 03:05PM -0300

>> (free functions, functors, member functions, lambdas, etc) with the
>> optional plus of binding/adding extra predefined values to your callback.
 
> Ugh. Obfuscated code for the sake of being clever.
 
Why obfuscated? why "clever"? on the contrary, this way of using events
and callback is very common. Also, it's very simple and more flexible
than callbacks based on virtual functions, here is a small contrived
example:
 
 
#include <functional>
#include <iostream>
#include <string>
 
 
class Foo {
public:
using event_type = std::function<
void(Foo&, const std::string& some_event_data)>;
 
event_type onStart;
event_type onStop;
 
 
void start() {
if (onStart) onStart(*this, "start event data");
 
// ...
}
 
void stop() {
if (onStop) onStop(*this, "stop event data");
 
// ...
}
};
 
 
////////////////////////////////////////////////////
class EventHandler {
Foo foo_;
 
public:
EventHandler() {
using namespace std::placeholders;
 
foo_.onStart = std::bind(&EventHandler::onStart, this, _1, _2);
foo_.onStop = std::bind(&EventHandler::onStop, this, _1, _2);
 
foo_.start();
}
 
~EventHandler() {
foo_.stop();
}
 
void onStart(Foo&, const std::string& data) {
std::cout << "on start: " << data << '\n';
}
 
void onStop(Foo&, const std::string& data) {
std::cout << "on start: " << data << '\n';
}
};
 
 
////////////////////////////////////////////////////
void onMyStart(Foo&, const std::string& data) {
std::cout << "on start: " << data << '\n';
}
 
void onMyStop(Foo&, const std::string& data) {
std::cout << "on stot: " << data << '\n';
}
 
 
////////////////////////////////////////////////////
int main() {
// Example 1 with free function callbacks
Foo foo;
 
foo.onStart = onMyStart;
foo.onStop = onMyStop;
 
foo.start();
foo.stop();
 
// Example 2 with member function callbacks
EventHandler handler;
}
 
 
--
Cholo Lennon
Bs.As.
ARG
Cholo Lennon <chololennon@hotmail.com>: Apr 23 03:47PM -0300

Fixed event messages:
 
 
#include <functional>
#include <iostream>
#include <string>
 
 
class Foo {
public:
using event_type = std::function<
void(Foo&, const std::string& some_event_data)>;
 
event_type onStart;
event_type onStop;
 
void start() {
if (onStart) onStart(*this, "start event data");
 
// ...
}
 
void stop() {
if (onStop) onStop(*this, "stop event data");
 
// ...
}
};
 
 
////////////////////////////////////////////////////
class EventHandler {
Foo foo_;
 
public:
EventHandler() {
using namespace std::placeholders;
 
foo_.onStart = std::bind(&EventHandler::onStart, this, _1, _2);
foo_.onStop = std::bind(&EventHandler::onStop, this, _1, _2);
foo_.start();
}
 
~EventHandler() {
foo_.stop();
}
 
void onStart(Foo&, const std::string& data) {
std::cout << "on start: " << data << '\n';
}
 
void onStop(Foo&, const std::string& data) {
std::cout << "on stop: " << data << '\n';
}
};
 
 
////////////////////////////////////////////////////
void onMyStart(Foo&, const std::string& data) {
std::cout << "on start: " << data << '\n';
}
 
void onMyStop(Foo&, const std::string& data) {
std::cout << "on stop: " << data << '\n';
}
 
 
////////////////////////////////////////////////////
int main() {
// Example 1 with free function callbacks
Foo foo;
 
foo.onStart = onMyStart;
foo.onStop = onMyStop;
 
foo.start();
foo.stop();
 
// Example 2 with member function callbacks
EventHandler handler;
}
Juha Nieminen <nospam@thanks.invalid>: Apr 23 07:38AM

> Never mind with such kind of people (this example is too complex for him).
> When feeling is good, C++ is a super-set of C
> When feeling is not so good, C++ is not C.
 
You had to quote 1600 lines of code in order to say that?
 
You do know that you can edit and shorten quotes, don't you?
Juha Nieminen <nospam@thanks.invalid>: Apr 23 07:55AM

> Attached is the source code for the 10th edition of Unix of the "ed"
> text editor, published by Brian Kernighan for his CS classes at
> Princeton in 2001.
 
Maybe it has significant historic value, but as a C program I don't think
it's that great.
 
It's quite hard to decipher (especially since it follows the typical
70's and 80's C style of using very short cryptic names everywhere),
but it appears to me that it has a fixed maximum line length of 4096.
I would guess you just can't edit lines longer than that.
 
(I also love how the program has one malloc() and no corresponding
free(), because why would it. It's not like it matters by the end
of the program...)
jacobnavia <jacob@jacob.remcomp.fr>: Apr 23 11:25AM +0200

Le 23/04/2021 à 09:55, Juha Nieminen a écrit :
> (I also love how the program has one malloc() and no corresponding
> free(), because why would it. It's not like it matters by the end
> of the program...)
 
If you look a bit longer, maybe you find out why, but maybe not, depends
on how far you can look.
wij <wyniijj@gmail.com>: Apr 23 05:12AM -0700

On Friday, 23 April 2021 at 15:38:49 UTC+8, Juha Nieminen wrote:
> > When feeling is not so good, C++ is not C.
> You had to quote 1600 lines of code in order to say that?
 
> You do know that you can edit and shorten quotes, don't you?
 
I do not really understand what 'quote' means here. So I reply
I can rewrite/translate ed.c as presented, using my own library easily and even
more powerfully and flexibly (file size would be larger and consume more resources).
My codes will not use 'stream stuff'(AT&T implicitly makes people believe it is the
'standard' everybody should follow), I use pure C-lib function calls, I follow the
standard C++ must follow as well.
 
If you rewrite ed.c (not yet a fully functional text editor) in pure C++,
what would be it look like? What would your evaluation be?
 
E.g. Let along signal and setjmp (and streaming I/O), I just pick one randomly.
I guess putchr('\n') might be translated to std::cout << std::endl. The point
here is std::endl. Could it be more elegantly and efficiently than
#define ENDL "\n" (C code)?
Maybe you would say you are talking memory allocation issues, but basically,
the main issue of your question is "No, C is not a simple language".
red floyd <myob@its.invalid>: Apr 23 09:24AM -0700

On 4/23/2021 5:12 AM, wij wrote:
>> You had to quote 1600 lines of code in order to say that?
 
>> You do know that you can edit and shorten quotes, don't you?
 
> I do not really understand what 'quote' means here.
[redacted]
 
What he means is, you didn't have to repost the entire C program to make
a four line comment on it. You could have edited it out, as I did here
with most of your comment
om@iki.fi (Otto J. Makela): Apr 23 07:25PM +0300


> Attached is the source code for the 10th edition of Unix of the "ed"
> text editor, published by Brian Kernighan for his CS classes at
> Princeton in 2001.
 
I like that it indeed does compile, but the fact that there are hardly
any comments, nor do the variable names really explain what is going on
hardly makes this a shining example of recommendable coding practices.
 
--
/* * * Otto J. Makela <om@iki.fi> * * * * * * * * * */
/* Phone: +358 40 765 5772, ICBM: N 60 10' E 24 55' */
/* Mail: Mechelininkatu 26 B 27, FI-00100 Helsinki */
/* * * Computers Rule 01001111 01001011 * * * * * * */
MrSpook__k@rw5_r42g0rzmn7wwf3izpl4.biz: Apr 17 03:16PM

On Sat, 17 Apr 2021 09:15:14 -0500
>Copyright 2021 Pete Olcott
 
Pretentious twat.
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: