Wednesday, February 1, 2023

Digest for comp.lang.c++@googlegroups.com - 22 updates in 3 topics

Zorro <zorabih@gmail.com>: Jan 31 03:25PM -0800

On Tuesday, January 31, 2023 at 4:29:42 PM UTC-6, Chris M. Thomasson wrote:
> > environment; perhaps it can call std::exit().
 
> True. I just pointed out that a C programmer is going to possibly get
> annoyed at the sheer sight of void main.
 
Thank you. ,Z++ is a "Superset", not an extension of C++, as it it to C. The list of
corrections to C++ is too long, here is a few simple ones:
 
The switch statement has an optional initial body where you can check something and return without
executing any of the cases. You can also declare objects that can be used in all "cases". The case
statements can be written as: "case 1..10:" instead of listing them all, or if not contiguous you can us commas,
as in: "case 1, 3, 12:". Since strings are built-in types, they can be used as case labels.
 
Z++ has a simple construct called pattern for specifying conditions for instantiating a template. e.g
template<type some-type : name-of-pattern>. At instantiation, the pattern is checked and if not followed
you will get an error.
 
The exception mechanism provides two forms of resumption: resume and repeat, with obvious semantics.
The debugger catches all exceptions defined in your program, that were raised but not caught, just as it
catches all memory leaks.
 
I will finish with this: Z++ classes and tasks (threaded classes) can have "invariant" which C++ can never
have with its heavy-weight exception mechanism which cannot even have a resumption. The reason is that
its compiler cannot catch exceptions thrown "by the compiler". It can only catch those thrown by user code.
 
Having said all of that, Z++ is for building platform-independent, "distributed" software. It is NOT to replace
C++ for making system software such as an IDE, just as C++ is NOT for writing operating systems. That is the
job of C.
scott@slp53.sl.home (Scott Lurndal): Feb 01 12:30AM


>Having said all of that, Z++ is for building platform-independent, "distributed" software. It is NOT to replace
>C++ for making system software such as an IDE, just as C++ is NOT for writing operating systems. That is the
>job of C.
 
Having written two commercial operating systems in C++ and two bare-metal hypervisors
in C++, I would dispute that assertion most vociferously.
 
Using carefully chosen subsets of the C++ language is perfectly acceptable and
generates code that compares favorably with C and allows the encapsulation
of data and methods in class structures.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jan 31 04:32PM -0800

Zorro <zorabih@gmail.com> writes:
[...]
> Thank you. ,Z++ is a "Superset", not an extension of C++, as it it to C.
 
What exactly do you mean by "Superset"?
 
If Z++ is truly a superset of C++, then every valid C++ program is a
valid Z++ program with the same semantics. If that's *nearly* the case,
as C++ is nearly a superset of C, then using the word with scare quotes
might be appropriate. If not, then you might consider using a different word.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for XCOM Labs
void Void(void) { Void(); } /* The recursive call of the void */
Paavo Helde <eesnimi@osa.pri.ee>: Feb 01 08:52AM +0200

01.02.2023 01:25 Zorro kirjutas:
 
> Thank you. ,Z++ is a "Superset", not an extension of C++, as it it to C. The list of
> corrections to C++ is too long, here is a few simple ones:
[...]> The case
> statements can be written as: "case 1..10:" instead of listing them all, or if not contiguous you can us commas,
> as in: "case 1, 3, 12:". Since strings are built-in types, they can be used as case labels.
 
This would make sense if there was an implicit 'break' at the end of
each 'case' (no fall-through), is that so?
Zorro <zorabih@gmail.com>: Feb 01 08:01AM -0800

On Wednesday, February 1, 2023 at 12:52:21 AM UTC-6, Paavo Helde wrote:
> > as in: "case 1, 3, 12:". Since strings are built-in types, they can be used as case labels.
> This would make sense if there was an implicit 'break' at the end of
> each 'case' (no fall-through), is that so?
 
 
Correct, each case body is a block in which you can declare objects visible within that block, and there is no
break at end of block (it is implicit).
Zorro <zorabih@gmail.com>: Feb 01 08:36AM -0800

On Tuesday, January 31, 2023 at 6:32:44 PM UTC-6, Keith Thompson wrote:
> Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
> Working, but not speaking, for XCOM Labs
> void Void(void) { Void(); } /* The recursive call of the void */
 
OK, initially C++ was called C with classes, around 1989 templates and exceptions were added.
For many years C++ was compiled to C, and the C compiler would finish the job. Thus, C++ is a
direct extension of C, even though now C++ compiler does the whole work. So now you only need
to indicate "extern "C"" for linkage purposes.
 
Consider definition of a class in Z++.
 
class some-name
//body
end;
 
There are no braces, but the class is defined same way as in C++, and it is multiple-inheritance.
However, private/protected (data) members can be specified as "visible". Then, they can be directly
accessed, but not modified.
 
A Z++ class can have any number of "invariant statements", and public methods can have "constraints"
as to what values or conditions must be satisfied so the method will be invoked (or exception will be raised).
 
Thus, the entire C++ class is within Z++ class, but there is a lot more, with minor difference in syntax, basically
no braces are used. This is not a direct extension of C++. Maybe we could say "semantically superset",
but that would be vague.
Muttley@dastardlyhq.com: Feb 01 05:10PM

On Wed, 1 Feb 2023 08:36:45 -0800 (PST)
>On Tuesday, January 31, 2023 at 6:32:44 PM UTC-6, Keith Thompson wrote:
>Thus, the entire C++ class is within Z++ class, but there is a lot more, with
>minor difference in syntax, basically
 
Using pascal style keywords instead of brackets is hardly a minor difference.
 
>no braces are used. This is not a direct extension of C++. Maybe we could say
>"semantically superset",
>but that would be vague.
 
One of the reasons Objective-C was unpopular was the mashing up of 2 different
syntax styles into one language. You should take note.
Paavo Helde <eesnimi@osa.pri.ee>: Feb 01 07:23PM +0200

01.02.2023 18:01 Zorro kirjutas:
>> each 'case' (no fall-through), is that so?
 
> Correct, each case body is a block in which you can declare objects visible within that block, and there is no
> break at end of block (it is implicit).
 
Ok, good!
 
About the built-in string type: is the encoding fixed? If it is variable
length like UTF-8, then do indexing and lengths happen in bytes or
unicode characters?
 
Is there a separate character data type?
 
Are they immutable like in Python? If immutable, are the contents
reference-counted? In a thread-safe way?
 
Is small string optimisation used?
 
Are zero bytes allowed in the middle of the string?
 
I'm curious because I have implemented a built-in string type for a
scripting language where all these questions came up.
Zorro <zorabih@gmail.com>: Feb 01 09:28AM -0800

On Tuesday, January 31, 2023 at 6:30:21 PM UTC-6, Scott Lurndal wrote:
 
> Using carefully chosen subsets of the C++ language is perfectly acceptable and
> generates code that compares favorably with C and allows the encapsulation
> of data and methods in class structures.
 
Every C++ class/struct will have to include a so-called virtual table. This is nothing more than the C "interrupt jump table",
which is a struct of pointers to functions to jump to. It did not come with C++ or other extensions of C like
Objective C. Every call to a method will also include a pointer "this" in C++ nomenclature. If instances to objects are passed
by value as argument, the copy constructor, as well as destructor, will be called on it. And other things I cannot think of now.
 
I agree, and even like the idea of writing certain parts of an operating system with C++. But not the whole thing. There are
things that even C cannot do, for which it has "inline" so assembler instructions can be inserted. Of course, C++ can do the
same.
 
Yes, "carefully chosen subset of C++" is a great idea, and has been done in the implementation of Z++.
scott@slp53.sl.home (Scott Lurndal): Feb 01 06:05PM

>> generates code that compares favorably with C and allows the encapsulation
>> of data and methods in class structures.
 
>Every C++ class/struct will have to include a so-called virtual table.
 
No, that is not the case. The virtual table is only present when
function overloads exist and in certain multiple inheritance
scenarios.
 
In those case, the overhead is no different that using the
traditional mechanisms of indirect calls through a
vector of function pointers (e.g. for Virtual File System
dispatch tables, or Scheduler dispatch tables, etc).
 
> This is nothing more than the C "interrupt jump table",
 
Actually, it is more, since the compiler handles it automatically
rather than the programmer having to create, initialize and
maintain the jump vectors.
 

 
>I agree, and even like the idea of writing certain parts of an operating
>system with C++. But not the whole thing.
 
The hypervisor:
 
SLOC Directory SLOC-by-Language (Sorted)
21708 dsm cpp=21708
17714 domain cpp=17714
12276 transport cpp=12276
8689 vserver cpp=8689
8162 debugger cpp=8162
6540 core cpp=6078,asm=462
6456 io cpp=6456
6074 xen cpp=6074
4820 mgmt cpp=4820
4390 mm cpp=4390
1829 include ansic=1286,cpp=543
1636 util cpp=1636
1608 bios cpp=1608
1234 interp cpp=1234
976 boot asm=976
518 tools ansic=403,sh=59,python=56
469 build ansic=248,cpp=221
222 platform cpp=222
0 doc (none)
0 top_dir (none)
 
 
Totals grouped by language (dominant language first):
cpp: 101831 (96.69%)
ansic: 1937 (1.84%)
asm: 1438 (1.37%)
sh: 59 (0.06%)
python: 56 (0.05%)
Zorro <zorabih@gmail.com>: Feb 01 10:07AM -0800

> >but that would be vague.
> One of the reasons Objective-C was unpopular was the mashing up of 2 different
> syntax styles into one language. You should take note.
 
We are not mashing up anything. Z++ syntax for constructs is like Eiffel or Ada. Z++ compiler will
not accept C or C++ programs, because it it not a plain extension of C++. There is only one syntax
and that is of Z++. However, over-all beyond constructs that need a closing tag, the rest is C++ syntax.
 
C++ won popularity (I am glad it did) because ATT sent B. Strousroup and G. Booch to all major shops
to introduce and advertise it. In the 90's ATT paid for an entire "Computer Journal" and filled it with rather
childish articles touting C++. A lot of money was spent on C++. Again, I like C++ as it is, so I am glad
it won.
 
Now, the reason for Z++ syntax, among many other things, is that it can catch and tell you what the error
is, and where it occurred. For instance, C++ compiler loses its view when a closing brace "}" is missed in
a nested statement, say "if within a loop", or even worse when nesting is too deep. That does not happen
in Z++. It can tell you what is missing, and where.
 
I reviewed all major languages, and weighed their syntax before deciding on the syntax for Z++. My intent
is not to advertise Z++ as "platform-independent" C++. Actually C++ is hardly about 60% of Z++. The main
Idea behind Z++ is distributed computing, which requires: component-orientation and platform-independence.
James Kuyper <jameskuyper@alumni.caltech.edu>: Feb 01 01:24PM -0500

On 2/1/23 11:36, Zorro wrote:
...
> For many years C++ was compiled to C, and the C compiler would finish the job. Thus, C++ is a
> direct extension of C, even though now C++ compiler does the whole work. So now you only need
> to indicate "extern "C"" for linkage purposes.
 
The C standard specifies the requirements for a conforming extension to
C: "A conforming implementation may have extensions (including
additional library functions), provided they do not alter the behavior
of any strictly conforming program." (4p6)
 
That's a very strict requirement, and it has been a very long time since
any version of C++ even came close to qualifying as an extension to C.
See Annex C.5 and C.6 of the C++ standard for a 10 page list of ways in
which C++ gives code that is permitted in both languages a significantly
different meaning than it would have as C code.
 
The C++ standard has similar language in 4.1p8, except that it uses
"well-formed" rather than "strictly conforming". There are significant
conceptual differences between "strictly conforming", as that term is
defined by the C standard, and "well-formed" as it is defined by the C++
standard, but they serve similar purposes in the two standards, and are
both very strict requirements. I sincerely doubt, from what you've said,
that Z++ even comes close to qualifying.
Zorro <zorabih@gmail.com>: Feb 01 10:57AM -0800

> standard, but they serve similar purposes in the two standards, and are
> both very strict requirements. I sincerely doubt, from what you've said,
> that Z++ even comes close to qualifying.
 
I think there is a big misunderstanding, sorry. Look, a program will consist of a lot of
statement such as:
 
new for creating dynamic objects
a++ or ++a for incrementing (and decrementing)
a << 4 or a <<= 4 and many other operators
pointer arithmetic
invoking methods, like p->method(...)
etc.
 
The syntax and semantics are identical to C++. But that is the bulk of a program. The main
difference is in the definitions, which are mostly extended. For instance:
 
enum something {....};
 
is exactly as in C++, but the values are private. Yes, C++ later added "enum class", but the work on
Z++ started in 1991 while I was still in academia. In addition, in Z++ you can extend enumeration:
 
enum another_thing : something {...};
 
Now, another_thing will include "something", and then add to it the new values.
 
Z++ does not have to deal with conforming to C++ standard, because it is not claiming to be
a direct extension of C++. It is a different language which uses the same syntax and semantics
for much of the statements that constitute a program. I hope this clarifies things somewhat.
Zorro <zorabih@gmail.com>: Feb 01 02:03PM -0800

On Wednesday, February 1, 2023 at 11:23:58 AM UTC-6, Paavo Helde wrote:
 
> Are zero bytes allowed in the middle of the string?
 
> I'm curious because I have implemented a built-in string type for a
> scripting language where all these questions came up.
 
As a built-in type it is an abstraction that can be extended in the future, only if needed. For now they are C-string
meaning single-byte ASCII characters. But of course one can create classes for whatever string kind
like unicode, UTF-8 etc, which then will not be built-in, and cannot be used as case labels. So, the answer to
your questions is no. Sorry.
gazelle@shell.xmission.com (Kenny McCormack): Jan 31 11:55PM

In article <1511fb1e-314d-42b5-8961-c76d45806430n@googlegroups.com>,
 
>Some people won't eat dog, and some people won't edit a binary. You
>probably won't change that streak in them. It just feels wrong to some
>people.
 
Exactly. And well put.
 
It really is, as you say, cultural.
 
--
Nov 4, 2008 - the day when everything went
from being Clinton's fault to being Obama's fault.
Paavo Helde <eesnimi@osa.pri.ee>: Feb 01 09:00AM +0200

30.01.2023 11:39 David Brown kirjutas:
> with post-compilation muddling of object files, it will /never/ be
> acceptable by anyone who takes security, reliability or maintainability
> seriously.
 
Why do you think he is targeting anyone who takes security seriously? So
far what I have gathered from his posts the aim is to get a precompiled
binary on users' computers, named 'ssh' and probably needing root
privileges to run (to "alter the routing table").
David Brown <david.brown@hesbynett.no>: Feb 01 09:07AM +0100

On 01/02/2023 08:00, Paavo Helde wrote:
> far what I have gathered from his posts the aim is to get a precompiled
> binary on users' computers, named 'ssh' and probably needing root
> privileges to run (to "alter the routing table").
 
I am assuming he is writing a program that he hopes will be useful to
people, rather than a rootkit or malware! And while end users rarely
know much about security, the people who put together Linux (or other
*nix) distributions do - if that is his ultimate aim for the program.
 
Of course, maybe he's just doing this for fun and the challenge.
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Feb 01 12:14AM -0800

On Wednesday, February 1, 2023 at 8:07:45 AM UTC, David Brown wrote:
 
> know much about security, the people who put together Linux (or other
> *nix) distributions do - if that is his ultimate aim for the program.
 
> Of course, maybe he's just doing this for fun and the challenge.
 
 
Again, I can't see your arguments amounting to more than "I don't eat dog because I come from a place where dogs are kept as pets".
 
You're adverse to editing object files, that's the summation of all of this.
 
The consequences of editing an object file can be determined from this 106-page document:
https://refspecs.linuxfoundation.org/elf/elf.pdf
 
The consequences of editing a C++ source file can be determined from this 1995-page document:
https://open-std.org/JTC1/SC22/WG21/docs/papers/2022/n4910.pdf
 
I'll go with the 106-pager.
 
Paavo wrote:
> far what I have gathered from his posts the aim is to get a precompiled
> binary on users' computers, named 'ssh' and probably needing root
> privileges to run (to "alter the routing table").
 
It will need privileges to create a TUN device and also to edit the routing table, so most people will run it using 'sudo', however I think there might be a way to grant these two privileges to the process without going all out and running it as root, I remember years ago selectively giving particular permissions to a process, it's been a while since I've done it.
David Brown <david.brown@hesbynett.no>: Feb 01 09:22AM +0100

On 31/01/2023 23:29, Frederick Virchanza Gotham wrote:
 
> Some people won't eat dog, and some people won't edit a binary. You
> probably won't change that streak in them. It just feels wrong to
> some people.
 
Kenny is a dedicated troll - he just posts to cause annoyance. There is
rarely any point in what he says, and even more rarely any point in
replying to him.
 
"Indoctrination" means that someone has repeatedly heard "do this" or
"don't do that" from a source they consider authoritative, and then they
follow those rules because of the authoritative source rather than
because they have considered the matter carefully themselves.
 
It is extremely rare that the topic of editing binaries as part of a
build process comes up - I have never read of it in any books, learned
of it in any course, or otherwise come across it in any serious context.
Ergo, it is impossible for my opinion on it to be the result of
indoctrination. And I think that applies to pretty much everyone.
 
 
As I have explained, manipulation of binaries can be appropriate as part
of a build process - I do it regularly. Your case is not appropriate
use. I have tried to explain way - based on /considered/ opinion and
not some "cultural" thing, indoctrination, or that it "feels wrong".
 
If you want people to thoughtlessly praise your cool tricks, take up
juggling or do magic shows for children. If you want people to give
honest opinions based on their knowledge and experience, come to a
newsgroup like this one.
 
But if you think it is better to insult or demean those who disagree
with you, you are on your own.
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Feb 01 05:53AM -0800

On Wednesday, February 1, 2023 at 8:22:36 AM UTC, David Brown wrote:
> of it in any course, or otherwise come across it in any serious context.
> Ergo, it is impossible for my opinion on it to be the result of
> indoctrination. And I think that applies to pretty much everyone.
 
 
Indoctrination can come from silence just as much as it can come from discussion. And it can some from a grey area between silence and discussion, like when people talk in parables or talk in a round-about way about something. There are some Christian churches near where I live who don't ever mention certain topics -- so children from the age of 4 up through their teenage years learn that it's "something you don't talk about".
 
I don't recall in my childhood people ever talking about farming dogs for food, but nonetheless I found the idea repugnant when I first heard it.

 
> of a build process - I do it regularly. Your case is not appropriate
> use. I have tried to explain way - based on /considered/ opinion and
> not some "cultural" thing, indoctrination, or that it "feels wrong".
 
 
Okay so then you think it's okay for some reasons, but not okay for others. Like if someone doesn't mind farming dogs for their hair but refuses to kill them and eat them. There's always a spectrum.
 
 
> newsgroup like this one.
 
> But if you think it is better to insult or demean those who disagree
> with you, you are on your own.
 
 
I'm making arguments here David, that's all. I've never sat at your desk and looked over your shoulder for a few hours, but you're probably good at your job. Two people can both be good at their job and still disagree on everything. There's more than one way to be a successful computer programmer.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Feb 01 01:55PM


>> Of course, maybe he's just doing this for fun and the challenge.
 
> Again, I can't see your arguments amounting to more than "I don't eat
> dog because I come from a place where dogs are kept as pets".
 
The "culture" analogy is OK, but picking that example is biased.
Editing object code rather than source code is something that is
relatively common in hacker culture. (One of the few times I've ever
edited a binary was to gain access to a system.) Editing source code
allows for reviews and auditing so is preferred in the security
conscious programming culture.
 
I'm not saying there is anything nefarious going on here, but it's not
simply a matter of taste as your analogy suggests.
 
> You're adverse to editing object files, that's the summation of all of
> this.
 
I'd say the my objection -- aversion if you will -- is not just a matter
of taste. Editing source code has all sort of very practical advantages
though there are times -- lost source for example -- when it's
impossible. That's the only other time I can recall doing this for any
practical purpose, and all the while I wished I had an alternative.
 
> this 1995-page document:
> https://open-std.org/JTC1/SC22/WG21/docs/papers/2022/n4910.pdf
 
> I'll go with the 106-pager.
 
That's a weird comparison. Neither tell you anything like what you need
to know about editing source or object files (in general).
 
--
Ben.
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Feb 01 02:07AM -0800

I have one thread that is reading and writing to a COM port, so it pretty much looks like this:
 
void Thread_Entry_Point(....)
{
for (;;)
{
Comms.Read( . . . );
ProcessPacket( . . . );
Comms.Write( . . . );
}
}
 
I have several worker threads which at any time can manually insert a packet into the COM port, and so the COM port thread looks more like this:
 
void Thread_Entry_Point(....)
{
string str;
 
for (;;)
{
str = Get_Manual_Packet();
 
if ( str.empty() ) Comms.Read( . . . );
else Comms.SetReadBuf(str.cbegin(), str.cend());
 
ProcessPacket( . . . );
Comms.Write( . . . );
}
}
 
I've spent the last two days figuring out deadlock and trying to put together a viable multithreaded locking system to make this possible. I have devised a two-stage lock to work as follows:
 
(Step 1) A worker thread, in order to manually insert a packet, must acquire both the primary lock and the secondary lock. When the worker thread is finished putting the packet into a global buffer, it then releases the secondary lock.
(Step 2) The COM port thread, when it calls "Get_Manual_Packet", tries to acquire the secondary lock. Once it has acquired the secondary lock, it processes the packet and sends it out the COM port, and reads back the reply.
(Step 3) Once the COM port thread has received the reply, it releases the secondary lock, and also releases the primary lock.
(Step 4) With both the primary and secondary lock now free, another worker thread can acquire both of them and manually insert another packet.
 
What makes this a little bit complicated is:
Complication 1) In Step 1, the worker thread acquiring the primary lock might be the most recent thread to have acquired the primary lock, and so it could try to double-lock a mutex (by the way I'm not using recursive mutexes at all).
Complication 2) In Step 3, it is the COM port thread that releases the primary lock even though it was a worker thread that acquired the lock.
 
In order to get around both Complication 1 and Complication 2, I have changed the primary lock from an "std::mutex" to a "std::atomic_flag". Instead of making a spin lock, I wait on the 'atomic_flag' to change.
 
Here's the code I've written so far. Please tell me if you see potential for deadlock or any other kind of multithreading debacle. By the way I realise there's a very minor race condition in the setting of "id_owner1" but that's only in Debug mode. The Comms thread calls the methods "lock_weak, unlock_weak", and the worker threads call "lock_strong, unlock_strong". The primary lock is 'device1' and the secondary lock is 'device2'.
 
#ifndef HEADER_INCLUSION_GUARD_TWO_STAGE_MUTEX_HPP
#define HEADER_INCLUSION_GUARD_TWO_STAGE_MUTEX_HPP
 
#include <cassert> // assert
#include <atomic> // atomic_flag, ATOMIC_FLAG_INIT
#include <mutex> // mutex, lock_guard
 
#ifdef NDEBUG
/* Nothing */
#else
# include <cstdlib> // abort
# include <thread> // thread::id, this_thread::get_id
# include <iostream> // cerr

No comments: