Sunday, April 18, 2021

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

Juha Nieminen <nospam@thanks.invalid>: Apr 18 04:25PM

> One reason C programmer do not like C++ is C++ does things in the background
> Good or bad? not easy to say shortly.
 
I can't think of many things that C++ "does in the background". Perhaps the
most prominent (and perhaps the most controversial) thing is exceptions.
However, even then, originally exceptions were accepted into the first C++
standard only if it could be proven that they could be implemented "for
free" (ie. exception support would not slow down the program in any way
if exceptions are not thrown). It's my understanding that the standardization
committee was satisfied enough with the techniques that were possible and
accepted them.
 
Of course one could also argue that RAII and compiler-generated constructors
and assignment operators are things that the compiler does "in the
background", but I would argue those are only beneficial, not detrimental.
And most importantly, they rarely come as a surprise to the programmer.
RAII certainly makes many things simpler (like in this example.)
 
(Rather obviously the standard library doesn't really count as "C++ doing
things in the background" because else you could make the same argument
from the C standard library.)
Juha Nieminen <nospam@thanks.invalid>: Apr 18 04:30PM

>>little experience even with other programming languages (he had some
>>very small experience with Python.)
 
> Umm, asprintf()
 
Use a non-standard-C non-posix compiler extension for... what, exactly?
Doesn't help one bit with allocation and deallocation of string
objects.
 
If you are going to suggest functions that are not part of the
standard language, you could just as well recommend using Python
or something.
 
> Any powerful language is hard to learn at the start. Try telling a beginner
> about C++ virtual function overloading or templates and watch the blank
> expression appear.
 
Why? He wanted to make a simple text editor, which manipulates dynamically
allocated strings. What do virtual functions or templates have anything
to do with this?
Juha Nieminen <nospam@thanks.invalid>: Apr 18 04:39PM

>> String str2 = String_with_cstr("there");
>> str1 = str2; // No!
 
> Did you try to explain him about why c++ has similar problems?
 
I always love it when C programmers try to come up with the most
contrived ways to defend their beloved language.
 
You didn't actually give an argument of why C would be better for the
beginner in question than C++, who only wanted to create a simple text
editor that manipulates dynamically allocated strings. Instead, you
deliberately came up with a contrived example that has nothing to do
with it.
 
> And of course you did NOT tell that beginner that he could avoid all
> accounting problems with strings if ne NEVER frees any string and just
> uses Boehm's GC that is available for C since more than a decade.
 
Why not just recommend him to use Python, while we are at it? All the
problems solved.
 
The funny thing is that you seem to be completely oblivious to the fact
that you are trying to recommend a fix to a flaw in the language, while
still defending the language.
 
 
> He could do:
> const String str = { 5, "hello"};
 
> But that is beyond the poor beginner's brain capacity or what?
 
I already explained why that's such a horrible idea in C, when the
'String' struct is supposed to hold a dynamically allocated string
that you are supposed to destroy before it goes out of scope.
 
You are writing that as if I didn't know that.
Juha Nieminen <nospam@thanks.invalid>: Apr 18 04:46PM

> ...
 
> This way there would be no ambiguity about how the STRING object has to
> be used.
 
I see no practical difference between that and a String struct. The usage is
pretty much the same, and all the same problems appear (such as assigning
one string object/pointer to another requiring extra care to avoid destroying
the string twice or accessing a destroyed string).
Juha Nieminen <nospam@thanks.invalid>: Apr 18 04:49PM

> Of course C is a very simple language, i.e. the language itself is very
> easy to understand.
 
Where does that misconception come from?
 
Even many experienced C programmers will have difficulty in understanding eg.
the most complex function and array pointers, or even remember their syntax
(there's a reason why sites like cdecl.org exist.)
Manfred <noname@add.invalid>: Apr 18 08:30PM +0200

On 4/18/2021 6:46 PM, Juha Nieminen wrote:
> pretty much the same, and all the same problems appear (such as assigning
> one string object/pointer to another requiring extra care to avoid destroying
> the string twice or accessing a destroyed string).
 
If the struct is opaque, the compiler won't allow you to assign a STRING
object to another, as a start. In fact it won't allow to perform /any/
operation on the object, except through the API that you define.
 
You can still mess up with pointers, but if you want to use C, then you
have to know better.
 
This is nothing new, as I wrote the entire FILE* infrastructure works
this way.
olcott <NoOne@NoWhere.com>: Apr 17 07:18PM -0500

On 4/17/2021 9:17 AM, olcott wrote:
> infinitely recursive unless X() stops it.
 
> The referenced execution trace is on x86 machine language, disassembled
> for human consumption.
 
void X(u32 P, i32 I)
{
Simulate(P, I);
}
 
void Y(u32 P)
{
X(P, P);
}
 
int main()
{
X((u32)Y, (u32)Y);
}
 
 
If the execution trace of function X() called by function Y() shows:
(1) Function X() is called twice in sequence from the same machine
address of Y().
(2) With the same parameters to X().
(3) With no conditional branch or indexed jump instructions in Y().
(4) With no function call returns from X().
then the function call from Y() to X() is infinitely recursive unless
X() stops it.
 
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
olcott <NoOne@NoWhere.com>: Apr 17 07:49PM -0500

On 4/17/2021 7:34 PM, Ben Bacarisse wrote:
> ...
 
> Note how X is called from Y+44 more than once with no branching or
> returns.
 
Lets simply assume x86 architecture and Intel syntax.
 
This is my latest revised infinite recursion halt deciding criteria:
 
If the execution trace of function X() called by function Y() shows:
(1) Function X() is called twice in sequence from the same machine
address of Y().
(2) With the same parameters to X().
(3) With no conditional branch or indexed jump instructions in Y().
(4) With no function call returns from X().
then the function call from Y() to X() is infinitely recursive unless
X() stops it.
 
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
Kaz Kylheku <563-365-8930@kylheku.com>: Apr 18 02:02AM

["Followup-To:" header set to comp.theory.]
 
> void X(u32 P, i32 I)
> {
> Simulate(P, I);
^^^^
 
This necessariy has a shitload of conditional execution in it.
 
> (4) With no function call returns from X().
> then the function call from Y() to X() is infinitely recursive unless
> X() stops it.
 
Wrong:
 
(3) a) With no conditional branch or indirect jump instructions
anywhere in the recursive loop, including the bodies of Y,
X, or any subroutine they call, or any child thereof.
 
b) There be no extensions to the Intel x86 instruction set.
which perpetrate conditional behavior inside the simulator
which subsequently affects the control flow.
 
The criterion that only Y has an basic block of instructions being
executed repeatedly are ridiculously insufficient for establishing that
there is a runaway recursion.
 
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Apr 17 07:05PM -0700

On 4/17/2021 5:18 PM, olcott wrote:
> (4) With no function call returns from X().
> then the function call from Y() to X() is infinitely recursive unless
> X() stops it.
 
Does your simulator handle the CMPXCHG instruction?
olcott <NoOne@NoWhere.com>: Apr 17 09:12PM -0500

On 4/17/2021 9:05 PM, Chris M. Thomasson wrote:
>> then the function call from Y() to X() is infinitely recursive unless
>> X() stops it.
 
> Does your simulator handle the CMPXCHG instruction?
 
The actual x86 emulator handles all of the x86 32-bit instructions.
If this screws up my criteria then I simply screen it out.
 
I may end up creating a machine much closer to a Turing machine except
that it will have 32-bit signed relative addressing at the very least.
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Apr 17 07:18PM -0700

On 4/17/2021 7:12 PM, olcott wrote:
>>> X() stops it.
 
>> Does your simulator handle the CMPXCHG instruction?
 
> The actual x86 emulator handles all of the x86 32-bit instructions.
 
Ahh, okay. So it can handle the LOCK prefix as well, right? CMPXCHG is a
32-bit instruction and, well, you know about the LOCK prefix so, thanks
for answering my question.
 
https://www.felixcloutier.com/x86/cmpxchg
 
https://www.felixcloutier.com/x86/lock
 
Does your simulator lock the bus, and/or the cache line in its emulation
of these instructions? Think of trying, and failing to lock the cache
line a bunch of times in a row, then finally resorting to the bus lock.
How do you do it in your simulator?
 
 
> If this screws up my criteria then I simply screen it out.
 
I do not know what you mean. CMPXCHG, XADD, XCHG, all of the x86 32-bit
instructions must be in your simulator right?
 
 
> I may end up creating a machine much closer to a Turing machine except
> that it will have 32-bit signed relative addressing at the very least.
 
Did you emulator x86 or not?
wij <wyniijj@gmail.com>: Apr 18 07:52AM -0700

On Saturday, 17 April 2021 at 22:18:02 UTC+8, olcott wrote:
> Copyright 2021 Pete Olcott
 
> "Great spirits have always encountered violent opposition from mediocre
> minds." Einstein
 
I can think of no easy way to detect infinite recursion in C++.
 
From the problem description:
 
Y: // no contiditonal branch
read_arg of Y
push_arg for X
call X
pop_arg for X
ret
 
X:
... // no return instruction
push_arg for Y
call Y
pop_arg for Y
... // no return instruction, probably unreachable
 
Obviously, both X() and Y() can never return. Then, what is the point?
Bonita Montero <Bonita.Montero@gmail.com>: Apr 18 06:12PM +0200

STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
STOP POSTING IN comp.lang.c/c++ !!!
olcott <NoOne@NoWhere.com>: Apr 18 11:16AM -0500

On 4/18/2021 11:12 AM, Bonita Montero wrote:
> STOP POSTING IN comp.lang.c/c++ !!!
 
Since this <is> relevant to C/C++ you can simply STFU !
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
Real Troll <real.troll@trolls.com>: Apr 18 05:23PM +0100

Did you use for loop to print all that crap?
 
 
On 18/04/2021 17:12, Bonita Montero wrote:
olcott <NoOne@NoWhere.com>: Apr 18 12:11PM -0500

On 4/18/2021 9:52 AM, wij wrote:
 
>> "Great spirits have always encountered violent opposition from mediocre
>> minds." Einstein
 
> I can think of no easy way to detect infinite recursion in C++.
 
The detection of the infinite recursion occurs at the machine language
level.
 
> pop_arg for Y
> ... // no return instruction, probably unreachable
 
> Obviously, both X() and Y() can never return. Then, what is the point?
 
The idea is to be able to define X() as a halt decider for functions
that call X() in infinite recursion.
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
Bonita Montero <Bonita.Montero@gmail.com>: Apr 18 07:33PM +0200

> Since this <is> relevant to C/C++ you can simply STFU !
 
It isn't relvant specifically to C/C++, it is relevant to any
language. So stop posting here.
olcott <NoOne@NoWhere.com>: Apr 18 12:35PM -0500

On 4/18/2021 12:33 PM, Bonita Montero wrote:
>> Since this <is> relevant to C/C++ you can simply STFU !
 
> It isn't relvant specifically to C/C++, it is relevant to any
> language. So stop posting here.
 
KNOW !
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
wij <wyniijj@gmail.com>: Apr 18 11:02AM -0700

On Monday, 19 April 2021 at 01:11:50 UTC+8, olcott wrote:
 
> > Obviously, both X() and Y() can never return. Then, what is the point?
 
> The idea is to be able to define X() as a halt decider for functions
> that call X() in infinite recursion.
 
Then, X() "You call it a halt decider", is defined not to return.
 
olcott <NoOne@NoWhere.com>: Apr 18 01:21PM -0500

On 4/17/2021 7:34 PM, Ben Bacarisse wrote:
> 0x000055555555512e <Y+5>: mov %rsp,%rbp
> 0x0000555555555131 <Y+8>: mov 0x2f15(%rip),%eax
> 0x0000555555555137 <Y+14>: lea 0x1(%rax),%edx
 
It is this line-of-code that has the same effect as simulating a
conditional branch using a jump table:
> 0x0000555555555160 <X+4>: push %rbp
> 0x0000555555555161 <X+5>: mov %rsp,%rbp
> 0x0000555555555164 <X+8>: callq 0x555555555129 <Y>
 
Simply restricting the model to the x86 architecture gets rid of this
problem. Since my purpose is to prove that there is at least one case
where a halt decider can correctly decide that it was called in infinite
recursion discarding an architectural model is a reasonable choice.
 
This is the revised infinite recursion detection criteria:
 
If the execution trace of function X() called by function Y() shows:
(1) Function X() is called twice in sequence from the same machine
address of Y().
(2) With the same parameters to X().
(3) With no conditional branch or indexed jump instructions in Y().
(4) With no function call returns from X().
then the function call from Y() to X() is infinitely recursive unless
X() stops it.
 
When X() detects that its simulation of Y() meets the above criteria
then X() can definitely stop simulating Y() to prevent its own infinite
execution.
 
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
olcott <NoOne@NoWhere.com>: Apr 18 01:24PM -0500

On 4/18/2021 1:02 PM, wij wrote:
 
>> The idea is to be able to define X() as a halt decider for functions
>> that call X() in infinite recursion.
 
> Then, X() "You call it a halt decider", is defined not to return.
 
When X() uses the following criteria to decide to stop simulating Y()
then X() has correctly decided that Y() would otherwise cause X() to
have infinite execution.
 
If the execution trace of function X() called by function Y() shows:
(1) Function X() is called twice in sequence from the same machine
address of Y().
(2) With the same parameters to X().
(3) With no conditional branch or indexed jump instructions in Y().
(4) With no function call returns from X().
then the function call from Y() to X() is infinitely recursive unless
X() stops it.
 
 
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
olcott <NoOne@NoWhere.com>: Apr 18 12:19PM -0500

On 4/18/2021 12:08 PM, Malcolm McLean wrote:
> reference external subroutine calls in the code. But the arrangement
> means that is now extremely easy to use data that the Turing machine
> does not have.
 
Look at it instead as C / x86 such that function X() in C that always
simulates its input detects when itself is called in infinite recursion.
 
If the execution trace of function X() called by function Y() shows:
(1) Function X() is called twice in sequence from the same machine
address of Y().
(2) With the same parameters to X().
(3) With no conditional branch or indexed jump instructions in Y().
(4) With no function call returns from X().
then the function call from Y() to X() is infinitely recursive unless
X() stops it.
 
Everything that has been alluded to as cheating is simply correct C code
correctly deciding that it has been called in infinite recursion on the
basis of examining the x86 execution trace of its caller according to
the above criteria.
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
Kaz Kylheku <563-365-8930@kylheku.com>: Apr 18 01:57AM

> execution trace shows no conditional branch instructions in Y() or
> function call returns from X() then the function call from Y() to X() is
> infinitely recursive unless X() stops it.
 
No, I do not agree. If the execution trace shows no conditional branch
instructions, then the situation is runaway recursive, period.
Nothing will stop it but stack exhaustion.
 
X doesn't do anything such as making a decision to terminate. If it did,
that would contradict the assumption that there are no conditional
instructions being executed in the recursive loop.
 
In your implementation of this, there are gaps in the instruction trace.
Y (called _H_Hat) invokes X (_Halts) via a CALL 00000883 instruction.
But the next element in the trace is not the address 00000833 which was
called, but, unexpectedy, but the address of _H_Hat itself, 00000a63.
 
There is a "trace black out" starting with 00000833 until 00000a63.
 
Your document also does not not show the disassembly listing of the
procedure at 00000833.
 
(I suspect that CALL 0000833 isn't a function call at all; the simulator
is rigged to recognize this address. You've hinted at the fact that
_Halts is a built-in simulation primitive and not an actual function.)
 
What you must do is provide a complete diassembly listing of all code
that is invoked. That code must be executed in accordance with the x86
instruction set architecture from Intel without any sneaky extensions.
There must be no puzzing gaps in the execution traces. If there is a
CALL X, the next instruction to be traced must be X.
 
You must also trace the value of every register. I.e add columns to the
trace for EAX, EBX, ... to show nothing is messing with their contents.
Just like your current trace has a surprising discontinuity in the EIP
register, any other register could have a surprising change not
reflected in what the instructions are doing.
Kaz Kylheku <563-365-8930@kylheku.com>: Apr 18 01:58AM

> execution trace shows no conditional branch instructions in Y() or a
> function call returns from X() then the function call from Y() to X() is
> infinitely recursive unless X() stops it.
 
Correction: "execution trace shows no conditional branch instructions
anywhere; not in Y, not in X"
 
continue ...
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: