Monday, April 19, 2021

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

wij <wyniijj@gmail.com>: Apr 18 10:06PM -0700


> > Therefore X() can only solve 'known instances', right?
 
> X() can detect a when it is called in infinite recursion by Y() which is
> an x86 function generated by a C compiler.
 
So, the answer is yes. X() can only solve existing 'known instances' AND
it also have to be an x86 function generated by a C compiler.
 
> This is sufficient to refute the conventional halting problem
> undecidability proofs.
 
If you think so.
https://en.wikipedia.org/wiki/Necessity_and_sufficiency
 
> {
> X((u32)Y, (u32)Y);
> }
 
I have been avoid mentioning the secondary issue that such codes are
very type dependent, suspicious to pass real tests.
olcott <NoOne@NoWhere.com>: Apr 19 09:49AM -0500

On 4/19/2021 12:06 AM, wij wrote:
>> an x86 function generated by a C compiler.
 
> So, the answer is yes. X() can only solve existing 'known instances' AND
> it also have to be an x86 function generated by a C compiler.
 
No, X() can solve an infinite set of instances where X() simulates Y()
and can examine the execution trace of Y() in some machine language.
 
>> }
 
> I have been avoid mentioning the secondary issue that such codes are
> very type dependent, suspicious to pass real tests.
 
I created that x86utm operating system and have been able to prove that
my halt decider correctly decides the above case for six months now.
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
wij <wyniijj@gmail.com>: Apr 19 09:12AM -0700

On Monday, 19 April 2021 at 22:49:19 UTC+8, olcott wrote:
> > very type dependent, suspicious to pass real tests.
 
> I created that x86utm operating system and have been able to prove that
> my halt decider correctly decides the above case for six months now.
 
If your, or anyone's, claim (no one can legitimately refute, in your logic) can be verified
by physical machines, you do not need people's confirmation, because the claim is
supported by physical machines, no one can refute.
Publish it in some way is enough (like astronomers spot a comet or found some
strange physic phenomena).
 
olcott <NoOne@NoWhere.com>: Apr 18 08:13PM -0500

On 4/18/2021 5:57 PM, Kaz Kylheku wrote:
 
> I have two remarks.
 
> Remark 1:
 
> This argument is irrefutable, because it is vacuously true.
I am rephrasing what I am saying to make it more clear:
 
(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().
 
void X(u32 P, i32 I)
{
Simulate(P, I);
}
 
void Y(u32 P)
{
X(P, P);
}
 
int main()
{
X((u32)Y, (u32)Y);
}
 
When X() simulates the machine language of Y() and examines resulting
execution trace after simulating each machine instruction of Y() then
X() can apply the criteria provided in the above to stop simulating Y()
on the basis that Y() would otherwise cause X() have infinite execution.
 
Do you agree with all that?
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
olcott <NoOne@NoWhere.com>: Apr 18 08:16PM -0500

On 4/18/2021 8:13 PM, olcott wrote:
 
>> I have two remarks.
 
>> Remark 1:
 
>> This argument is irrefutable, because it is vacuously true.
 
 
I am rephrasing what I am saying to make it more clear:
 
Infinite recursion detection criteria:
(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().
 
void X(u32 P, i32 I)
{
Simulate(P, I);
}
 
void Y(u32 P)
{
X(P, P);
}
 
int main()
{
X((u32)Y, (u32)Y);
}
 
When X() simulates the machine language of Y() and examines resulting
execution trace after simulating each machine instruction of Y() then
X() can apply the criteria provided in the above to stop simulating Y()
on the basis that Y() would otherwise cause X() have infinite execution.
 
Do you agree with all that?
 
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
olcott <NoOne@NoWhere.com>: Apr 18 09:16PM -0500

On 4/18/2021 9:13 PM, Richard Damon wrote:
>> on the basis that Y() would otherwise cause X() have infinite execution.
 
>> Do you agree with this?
 
> With the code provided here, X has no conditions at all,
 
No try again you are not paying close enough attention, it never says
that X() has no conditional code.
 
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
Richard Damon <Richard@Damon-Family.org>: Apr 18 10:26PM -0400

On 4/18/21 10:16 PM, olcott wrote:
 
>> With the code provided here, X has no conditions at all,
 
> No try again you are not paying close enough attention, it never says
> that X() has no conditional code.
 
But X() was defined as:
 
>>> {
>>> Simulate(P, I);
>>> }
 
You have previous defined that Simulate is a regular UTM function.
 
I see no conditional in that function.
 
 
Your logic in inconsistent.
olcott <NoOne@NoWhere.com>: Apr 18 09:29PM -0500

On 4/18/2021 9:26 PM, Richard Damon wrote:
 
> You have previous defined that Simulate is a regular UTM function.
 
> I see no conditional in that function.
 
> Your logic in inconsistent.
 
I have never ever defined X() as a UTM anything. X has always only been
C code. You have to pay attention to what I am actually saying not what
you think that I mean.
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
olcott <NoOne@NoWhere.com>: Apr 19 10:40AM -0500

On 4/19/2021 10:28 AM, Richard Damon wrote:
 
> This sub-thread was NOT about X being a UTM. It was about you talking
> about conditional execution inside X when you provided a definition of
> X() that hand NO conditional execution.
 
Do you have OCD? You keep getting key points incorrectly.
 
These four points are examined as the basis of determining that Y() is
calling X() in infinite recursion.
 
I never said that X() does not have conditional branch instructions.
 
I only said that they are not part of the basis for correctly deciding
that Y() has called X() in infinite recursion.
 
It turns out that these four points are a sufficient condition for
correctly deciding that Y() is calling X() in infinite recursion.
 
(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().
 
The following code (including an x86 emulator) is written in "C"
 
void X(u32 P, u32 I)
{
Simulate(P, I);
}
 
void Y(u32 P)
{
X(P, P);
}
 
int main()
{
X((u32)Y, (u32)Y);
}
 
When X() simulates the x86 machine language of Y() and examines
resulting execution trace after simulating each machine instruction of
Y() then X() can apply the criteria provided above to correctly decide
to stop simulating Y() on the basis that Y() would otherwise cause X()
have infinite execution.
 
 
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
Andrey Tarasevich <andreytarasevich@hotmail.com>: Apr 19 08:16AM -0700

Hello
 
A simple example
 
class A
{
};
 
class B : A
{
A *p; // 1 - OK
};
 
class C : B
{
A *p; // 2 - Error
};
 
The declaration at point 2 is invalid, since it refers to injected class
name `A` in `A`. That name is inaccessible in `C`.
 
But what about point 1? Does it also refer to injected class name `A` in
`A`? If so, it shouldn't compile either, since innards of `A` are
inaccessible in `B`.
 
Yet, it compiles. Apparently, when `A` is a direct base, unqualified
name lookup finds a different access path to `A` (not the injected class
name).
 
What exactly does it find? Where is it described in the standard? Is it
something as simple as "base class list is also searched during
unqualified name lookup"?
 
--
Best regards,
Andrey Tarasevich
Ben Bacarisse <ben.usenet@bsb.me.uk>: Apr 19 01:36AM +0100


> 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.)
 
C++ includes almost all of those. And it throws a few more bits and
pieces into to mix (&, &&, pointer-to-member and so on).
 
--
Ben.
Juha Nieminen <nospam@thanks.invalid>: Apr 19 07:18AM

> 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.
 
I see no difference between your scheme and mine.
 
String str1 = String_with_cstr("hello");
String str2 = str1;
// lots of code here
String_free(str1);
String_free(str2); // oops
 
vs.
 
String* str1 = String_with_c_str("hello");
String* str2 = str1;
// lots of code here
String_free(str1);
String_free(str2); // oops
 
> You can still mess up with pointers, but if you want to use C, then you
> have to know better.
 
My point is that for a beginner it's so much simpler to be able to do:
 
std::string str1 = "hello";
std::string str2 = str1;
// lots of code here
// no need to even destroy those strings, they'll be destroyed
// automatically
 
It's also significantly easier to try to guide a beginner to create a small
project like I described.
 
(Sure, you can start arguing about the efficiency issues of std::string
always making a deep copy whenever it's passed around, but this is just
trying to guide a beginner to do one of his first projects. The efficiency
questions can come up much, much later in the learning process. At this
point the efficiency issues are completely irrelevant.)
Juha Nieminen <nospam@thanks.invalid>: Apr 19 07:19AM

>> (there's a reason why sites like cdecl.org exist.)
 
> C++ includes almost all of those. And it throws a few more bits and
> pieces into to mix (&, &&, pointer-to-member and so on).
 
I was not commenting on the complexity of C++. I was commenting on the
claim that C is "very easy to understand".
 
No, it's not. Not in all cases, even when we aren't dealing with deliberately
obfuscated code.
Juha Nieminen <nospam@thanks.invalid>: Apr 19 07:22AM

> length arrays in C, and I only use std::vector in C++. In several
> decades as a professional programmer I have never allocated memory in C
> or C++.
 
That's not always something you can avoid. Sometimes you need to, for example,
read an entire file into RAM. You can't just go and use a fixed-length
array for that.
 
(Just reading an entire file into RAM and doing something basig to it is
simple enough in C. However, it starts becoming complicated once you need
to start modifying parts of it such that they will grow larger. Like
inserting things into lines of text.)
MrSpook_wyzaq1485z@solbi8e3oaumg9.gov.uk: Apr 19 07:42AM

On Sun, 18 Apr 2021 16:30:13 +0000 (UTC)
>>>very small experience with Python.)
 
>> Umm, asprintf()
 
>Use a non-standard-C non-posix compiler extension for... what, exactly?
 
Its a defacto function standard found on Linux, BSD and MacOS and thats good
enough for me.
 
>Doesn't help one bit with allocation and deallocation of string
>objects.
 
Sorry? Allocation of the correct size string for the format is its raison
d'etre!
 
>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.
 
Sockets arn't part of the standard language so how would you suggest solving
networking issues using the language? Inline assembler?
 
 
>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?
 
*sigh* It helps if you read whats been written before replying.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Apr 19 11:36AM +0100

>> pieces into to mix (&, &&, pointer-to-member and so on).
 
> I was not commenting on the complexity of C++. I was commenting on the
> claim that C is "very easy to understand".
 
Ah, sorry. It would have been a bit clearer (since the discussion was
comparative) to say that both C and C++ have complex declaration syntax.
 
I get that you were countering the misconception that C is "very easy to
understand". Maybe you simply took it for granted that C++ wasn't very
easy to understand and it didn't need to mentioned.
 
> No, it's not. Not in all cases, even when we aren't dealing with deliberately
> obfuscated code.
 
The usual advice, in both languages, is not to use the available syntax.
 
--
Ben.
wij <wyniijj@gmail.com>: Apr 19 06:43AM -0700

On Monday, 19 April 2021 at 00:26:07 UTC+8, Juha Nieminen wrote:
 
> (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.)
 
Once upon a time, C++ claimed being a superior system programming language.
Luckily, Linus Torvalds was not fooled as most C++ beginners were.
Such kind of topic (like, C/C++ which one is better) had been heavily discussed
several times before, in ways like debating which religion is better.
Just do not be overly zealous.
olcott <NoOne@NoWhere.com>: Apr 19 09:50AM -0500

On 4/19/2021 2:22 AM, Juha Nieminen wrote:
 
> That's not always something you can avoid. Sometimes you need to, for example,
> read an entire file into RAM. You can't just go and use a fixed-length
> array for that.
 
I read it into a std::vector that has its capacity set to the file size.
 
 
--
Copyright 2021 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
Bonita Montero <Bonita.Montero@gmail.com>: Apr 19 04:54PM +0200

> claim that C is "very easy to understand".
> No, it's not. Not in all cases, even when we aren't dealing with deliberately
> obfuscated code.
 
What I said wasn't related to actual code. Code could be
hard to understand also in even simpler languages like
Java. But the rules of the language are almost completely
easy to understand.
Manfred <noname@add.invalid>: Apr 19 05:15PM +0200

On 4/19/2021 9:18 AM, Juha Nieminen wrote:
> // lots of code here
> String_free(str1);
> String_free(str2); // oops
 
I do see a difference there, and it is the tiny little '*' in
> String* str2 = str1;
 
Which means that you are duplicating a pointer to an object and this
should trigger extra attention wrt object lifetime (and other things for
that matter).
Would you ever write with any lightness:
FILE* f1 = fopen("foo", "r");
FILE* f2 = f1;
// ...
 
If you want to use C you should get trained to this kind of details.
However, I get that this is probably what you mean by C being not simple
- it is not.
My point is that if you are using C, and you are familiar with it, then
there is a difference between the two designs.
 
(An example where your design is perfectly OK and widely used:
typedef struct point_t
{
int x;
int y;
} POINT;
 
POINT p1 = {42, 42};
POINT p2 = p1;
...
 
But here you make sure that the type is safely (trivially) copyable, a.o.)
 
> // automatically
 
> It's also significantly easier to try to guide a beginner to create a small
> project like I described.
 
I'd comment about the term "easy" - you still need to know how RAII and
stuff works here, even if it all happens automatically.
I'd say that the fact that it happens behind the scenes might even make
it harder for a beginner.
The code /looks/ simpler, the mechanics of it is not - C++ is not simple
either.
 
Considering C++ simple is a major source of mistakes, IMO.
 
> trying to guide a beginner to do one of his first projects. The efficiency
> questions can come up much, much later in the learning process. At this
> point the efficiency issues are completely irrelevant.)
 
Agreed, performance has no relevance here.
Bonita Montero <Bonita.Montero@gmail.com>: Apr 19 11:23AM +0200

I just tested std::bind with a member-function trick
and C++20 under MSVC:
 
#include <functional>
#include <utility>
 
template<typename T, typename RetType, typename ... Args>
auto obj_binder( T *this_, RetType (T::*fn)( Args ... ), Args &&...args )
{
using namespace std;
auto binderFn = []<typename T, typename RetType, typename ... Args>( T
* this_, RetType (T::*fn), Args &&...args ) -> RetType
{
return this_->*fn( forward<Args>( args ) ... );
};
return bind( binderFn, this_, fn, std::forward<Args>( args ) ... );
}
 
int main()
{
struct S
{
int a, b, c;
int sum( int d )
{
return a + b + c + d;
}
};
S s;
s.a = s.b = s.c = 1;
auto bound = obj_binder<S, int>( &s, &S::sum, 4 );
}
 
Unfortunately the compiler crashes with this.
C++20-support is still experimental with MSVC.
MrSpook_78@xvdv0t9masednkplrcjyxfsl.tv: Apr 19 09:32AM

On Mon, 19 Apr 2021 11:23:17 +0200
>Unfortunately the compiler crashes with this.
 
My brain jusr crashed trying to understand what its supposed to do.
Bonita Montero <Bonita.Montero@gmail.com>: Apr 19 01:04PM +0200

>> Unfortunately the compiler crashes with this.
 
> My brain jusr crashed trying to understand what its supposed to do.
 
std::bind doesn't work with objects and member-functions.
So I wrote a obj_binder which you can supply an object
-pointer, a member-function within this object and the
parameters for this function. Later you can call this
generated object like bound().
Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 18 08:04PM -0700


> For example, if you're reading a 16-bit integer, limiting the field
> width means you can't read values over 9999 -- or, if I'm not mistaken,
> values less than -999 for a 16-bit signed integer.
 
True, but the value could be read into a long long, which in most
cases will suffice to read a desired input value safely.
 
If it's important to read values near the boundaries of what, for
example, integer types can represent, it is still always possible
to read the input safely using scanf, even if not as conveniently
as one might like.
 
Of course usually it's easier to read in lines and use sscanf()
on those, but the principle is the same.
 
(I will note for the record that these comments don't apply in
the case of a %p conversion specification. I assume no one was
talking about those.)
Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 18 07:14PM -0700

> contents of that memory can represent values don't make it any less a
> piece of memory. It's just a piece of memory with which the
> implementation (may have) associated a particular type.
 
All objects occupy regions of memory, but not all regions of
memory are occupied by objects. Some regions of memory are
occupied by several different objects, often with different
types. Some regions of memory correspond to part of an object,
but not to any whole object. And of course a region of memory
could correspond to part of one object and part of another
object, with different types, but not to any whole object.
There is no sense in which any of those regions of memory has
a type (in the C language sense of the word type).
 
Memory does not have a type. Objects have a type, but memory
does not have a type.
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: