Tuesday, September 20, 2022

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

Lynn McGuire <lynnmcguire5@gmail.com>: Sep 19 08:23PM -0500

On 9/19/2022 3:48 PM, Mr Flibble wrote:
 
> There is no reason to ever use "using namespace std;" at global scope
> and any benefit is outweighed by disadvantages.
 
> /Flibble
 
I have to admit that we have the size () method sprinkled throughout a
least a hundred of our classes. std::size () really messed with that
when we jumped from MSVC 6 to MSVC 2005 ???. We used the "using
namespace std;" which bit us hard in a couple of cases.
 
Lynn
Bonita Montero <Bonita.Montero@gmail.com>: Sep 20 05:38AM +0200

Am 19.09.2022 um 22:48 schrieb Mr Flibble:
 
> There is no reason to ever use "using namespace std;" at global scope
> and any benefit is outweighed by disadvantages.
 
> /Flibble
 
There are no drawbacks except for compulsive people.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 20 05:38AM +0200

Am 19.09.2022 um 22:59 schrieb Lynn McGuire:
> there is more than one method that meets the conditions.  Been there,
> done that with Visual C++ back in the 2000s.
 
> Lynn
 
You can't be a good programmer since your first thought here isn't
that you definitely get en error.
Juha Nieminen <nospam@thanks.invalid>: Sep 20 06:18AM

> This doesn't depend on the size of the code.
> As re-using symbols of std is uncommon in other namespaces and
> the compiler would error for clashes anyway this isn't a deal.
 
If you are such a C++ expert as you portray yourself to be, you should
know better than that.
 
Using the same name with two different functions doesn't necessarily
cause a name clash. It's called overloading. And the funny thing about
overloading is that if a new overloaded version of a function is
introduced in addition to the old existing one, some already existing
function calls might suddenly start calling the new one rather than
the old one, if the new one matches better.
 
When that happens deliberately then it's fine. However, when that
happens inadvertently it can cause really obscure bugs, as code that
has been compiling and working for a long time still compiles just
fine... but starts working incorrectly at runtime.
 
And the thing is, the newly introduced "overloaded" function might
come from the standard library, when a new #include line is added
somewhere.
 
You say that "re-using symbols of std is uncommon". Yeah, I'm sure that
you remember the literally hundreds and hundreds, maybe thousands, of
names in the standard library by heart.
Juha Nieminen <nospam@thanks.invalid>: Sep 20 06:20AM

>> done that with Visual C++ back in the 2000s.
 
> You can't be a good programmer since your first thought here isn't
> that you definitely get en error.
 
Apparently you don't know what function overloading is.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 20 08:21AM +0200

Am 20.09.2022 um 08:18 schrieb Juha Nieminen:
>> the compiler would error for clashes anyway this isn't a deal.
 
> If you are such a C++ expert as you portray yourself to be, you should
> know better than that.
 
That's not a matter of knowledge but of personal style.
I wont't read the rest of what you write to persuade me
to adhere to your personal style.
Juha Nieminen <nospam@thanks.invalid>: Sep 20 06:38AM

> I wont't read the rest of what you write to persuade me
> to adhere to your personal style.
 
Which automatically invalidates everything you say. You have no
counter-arguments to what I wrote, and you are too afraid to even
read what I wrote, and instead you are resorting to the age-old
arrogant and provocative "I'm so far beyond you that I'm not even
going to give you the dignity of reading what you have written".
 
Why people here are *still* taking you seriously and responding to
you seriously is beyond my comprehension.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 20 09:08AM +0200

Am 20.09.2022 um 08:38 schrieb Juha Nieminen:
>> to adhere to your personal style.
 
> Which automatically invalidates everything you say. You have no
> counter-arguments to what I wrote, ...
 
The counter argument is: I'm programming like this for
29 years in C++ and I never ran into problems with that.
David Brown <david.brown@hesbynett.no>: Sep 20 09:35AM +0200

On 19/09/2022 22:12, Bonita Montero wrote:
 
> This doesn't depend on the size of the code.
> As re-using symbols of std is uncommon in other namespaces and
> the compiler would error for clashes anyway this isn't a deal.
 
Nameclashes with std /are/ common, and get more common as the standard
library increases in size. The whole point of having the standard
library in the std:: namespace is that the C++ committee are free to add
whatever names they feel appropriate, without fear of breaking existing
code or limiting other programmers.
 
If you have a global "using namespace std;", and there are clashes, then
it /might/ lead to a clear compiler error. But it might not - it could
well be that overload or template resolution simply leads to the wrong
function being called, with no warning until you get obscure effects
during testing.
 
And even if compile-time errors were guaranteed, what help is that when
you take a large existing C++14 code base that has been extensively
tested and debugged, then suddenly there are problems and collisions
when you move to C++17 or C++20.
 
Namespaces were added to C++ because at that time, decades ago,
identifier collisions were a big problem in large C codebases. They
have been a major tool ever since. Adding global "using namespace"
directives, especially for namespaces that are not fully under your own
control, is throwing out that tool.
 
It is fine to have "using namespace" in smaller scopes - such as inside
a function. Occasionally you might want to import a namespace into an
entire implementation file (not a header), but not for "std". If you
had the habit of putting "using namespace std;" /inside/ main() or other
sample function, you'd see far fewer objections.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 20 12:08PM +0200

Am 20.09.2022 um 09:35 schrieb David Brown:
 
> library in the std:: namespace is that the C++ committee are free to add
> whatever names they feel appropriate, without fear of breaking existing
> code or limiting other programmers.
 
This isn't the only aspect for that.
 
 
> well be that overload or template resolution simply leads to the wrong
> function being called, with no warning until you get obscure effects
> during testing.
 
That's unlikely and that would be my problem.
And this problem has never been shown with the code I posted here.
 
> It is fine to have "using namespace" in smaller scopes - ...
 
No, the same name clashes could arise.
 
I'm sure you and Juha continue your mission for the next 10 years.
You're both insane.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Sep 20 05:59AM -0700

> going to give you the dignity of reading what you have written".
 
> Why people here are *still* taking you seriously and responding to
> you seriously is beyond my comprehension.
 
Yes, why do you continue to respond to her?
 
You need to learn the fine art of not replying.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
scott@slp53.sl.home (Scott Lurndal): Sep 20 01:49PM


>> You can't be a good programmer since your first thought here isn't
>> that you definitely get en error.
 
>Apparently you don't know what function overloading is.
 
And apparently you don't know how to ignore the trolls.
Lynn McGuire <lynnmcguire5@gmail.com>: Sep 20 04:18PM -0500

On 9/20/2022 8:49 AM, Scott Lurndal wrote:
>>> that you definitely get en error.
 
>> Apparently you don't know what function overloading is.
 
> And apparently you don't know how to ignore the trolls.
 
Sadly it does appear that way.
 
Lynn
Bonita Montero <Bonita.Montero@gmail.com>: Sep 20 11:49PM +0200

Am 20.09.2022 um 23:18 schrieb Lynn McGuire:
 
>> And apparently you don't know how to ignore the trolls.
 
> Sadly it does appear that way.
 
> Lynn
 
Sorry, others try to dictate my style and we're not in the same project.
And you call me trollng ?
Bonita Montero <Bonita.Montero@gmail.com>: Sep 20 04:18PM +0200

I experimented with loop unrolling in C++20 and I found that sometimes
its the best to to interleaved steps while unrolling. F.e. you load
multiple values into the registers in the first step, then process
these values interleaved and then have some interleaved write back.
This is usually somewhat awkward to program because you have code
parts which are replicated, usually differing only in some array
indices of the data you process.
 
So I extended my unrolling helper, here it is:
 
template<size_t N, typename ... Fns>
requires (N >= 1) && (requires( Fns fn ) { { fn.template operator
()<(size_t)N - 1>() } -> std::same_as<void>; } && ...)
inline void unroll( Fns ... fns )
{
auto unroll_n = [&]<typename Fn, size_t ... Indices>( Fn fn,
std::index_sequence<Indices ...> )
{
(fn.template operator ()<Indices>(), ...);
};
(unroll_n( fns, std::make_index_sequence<N>() ), ...);
}
 
This whole interleaving then might look like this:
 
unroll<3>(
[]<size_t I>() { cout << "step 1, interleave " << I << endl; },
[]<size_t I>() { cout << "step 2, interleave " << I << endl; },
[]<size_t I>() { cout << "step 3, interleave " << I << endl; } );
 
 
Doesn't look good but the manual way is even worse.
Muttley@dastardlyhq.com: Sep 20 03:41PM

On Tue, 20 Sep 2022 16:18:25 +0200
 
>template<size_t N, typename ... Fns>
> requires (N >= 1) && (requires( Fns fn ) { { fn.template operator
>()<(size_t)N - 1>() } -> std::same_as<void>; } && ...)
 
Larry Wall must be starting to get envious of C++ syntax these days.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 20 06:37PM +0200

>> requires (N >= 1) && (requires( Fns fn ) { { fn.template operator
>> ()<(size_t)N - 1>() } -> std::same_as<void>; } && ...)
 
> Larry Wall must be starting to get envious of C++ syntax these days.
 
That's all a matter of whether you've learned this or not.
If you learned it it's not hard to read.
And I don't know what you do in a C++ group, criticizing C++.
olcott <polcott2@gmail.com>: Sep 20 11:33AM -0500

This is an explanation of a possible new insight into the halting
problem provided in the language of software engineering. Technical
computer science terms are explained using software engineering terms.
No knowledge of the halting problem is required.
 
When the conventional "pathological" input (that does the opposite of
whatever the halt decider decides) is the first argument to a simulating
halt decider then this input becomes decidable as specifying infinitely
recursive simulation.
 
This paper is based on fully operational software executed in the x86utm
operating system. The x86utm operating system (based on an excellent
open source x86 emulator) was created to study the details of the
halting problem proof counter-examples at the much higher level of
abstraction of C/x86.
 
typedef void (*ptr)();
int H(ptr p, ptr i); // simulating halt decider
 
// P does the opposite of whatever H decides
void P(ptr x)
{
int Halt_Status = H(x, x);
if (Halt_Status) // if H(P,P) reports that its input halts
HERE: goto HERE; // P loops and never halts
return; // else P halts
}
 
int main()
{
Output("Input_Halts = ", H(P, P));
}
 
// This H(P,P) specifies the direct execution of P(P)
// which obviously never stops running
int H(ptr x, ptr y)
{
x(y);
}
 
Halting: is defined as:
*reaching the last instruction (AKA final state) and stopping*
 
When an H is defined that correctly determines that the above direct
execution of P(P) would never reach its "return" instruction (AKA final
state) the conventional halting problem proofs are refuted.
 
All halt deciders are intended to predict the behavior of their inputs
without actually executing these inputs because the halt decider itself
must always halt. The method used to determine that the above P(P) never
halts is a slight adaptation of a similar method that correctly detects
infinite recursion.
 
When a correct non-halting behavior pattern is matched a simulating halt
decider (SHD) aborts its simulation and returns 0. Halting does not mean
stops running, halting only means reaching the last instruction and
stops running.
 
Because we can see that the direct execution of P(P) from H would never
reach the last "return" instruction of P we know that no complete or
partial simulation of P by H would ever reach this last instruction of
P. From this we know that P is non-halting.
 
*Complete halt deciding system including*
*(a) x86utm operating system*
*(b) complete x86 emulator*
*(c) Several halt deciders and their inputs contained within Halt7.c*
https://liarparadox.org/2022_09_07.zip
 
*Currently compiles under*
Microsoft Visual Studio Community 2017
https://visualstudio.microsoft.com/vs/older-downloads/
 
 
 
 
--
Copyright 2022 Pete Olcott "Talent hits a target no one else can hit;
Genius hits a target no one else can see." Arthur Schopenhauer
Juha Nieminen <nospam@thanks.invalid>: Sep 20 09:48AM

The standard states (if I understand correctly) that inline functions
with the same signature must have identical implementations, else
the behavior is undefined.
 
(In practice what will most likely happen if two different inline
functions have the same signature is that, in case they don't
actually get inlined and are instantiated on their own, the linker
will just choose one of the instances and drop the others. Which
means that code that was calling the others will now be calling
this one, likely to cause misbehavior, if the different versions
of this function weren't doing exactly the same thing.)
 
This got me thinking: I assume that, quite naturally, this requirement
extends to template functions (which are effectively "inline" by
default).
 
However, in this case it might be easier to create different
"inline" templated functions that have different implementations,
even though there's only one implementation in the source code
itself. The template function may produce different code depending
on the context.
 
I suppose that if it's the compiler itself that's producing different
code depending on the context in which the template is instantiated,
that doesn't really matter (because the programmer didn't do anything
wrong here; it's all on the compiler, well beyond the hands of the
programmer).
 
However, it might sometimes be easy to accidentally write templated
code that actually produces a different implementation depending on
the context in which the template is instantiated.
 
Suppose, for example, that the template function is something like:
 
template<typename T>
void foobar(const T& value)
{
std::cout << "The value is: " << value << "\n";
}
 
Now in some source file the programmer might be too clever for his
own good and actually overload the operator<< for a particular
type. Heck, there may be different overload implementations in
different source files.
 
However, it can get even subtler than that. For example, you could have
in some header something along the lines of:
 
const std::string kSomeString = "hello";
 
template<typename T>
void foobar(const T& value)
{
std::cout << kSomeString << ": " << value << "\n";
}
 
It might not be immediately apparent what the problem is. However, the
problem is that a const object has internal linkage by default, meaning
that the above std::string object is effectively the same thing as:
 
static const std::string kSomeString = "hello";
 
which in turn means that it will have its own unique instance in each
compilation unit where it's used. Which in turn means that the template
function will be pointing to a different object in each such compilation
unit. Which in turn means that, technically speaking, all these instances,
which have the same signature, have a different implementation.
 
"Who cares? All the string objects contain the same content. The end
result is the same."
 
Maybe. However, in some cases the thing outside the template function
might not be the same. Maybe what the std::string is initialized with
depends on which source code it is included into.
Sam <sam@email-scan.com>: Sep 20 06:51AM -0400

Juha Nieminen writes:
 
> own good and actually overload the operator<< for a particular
> type. Heck, there may be different overload implementations in
> different source files.
 
This would be an ODR violation of the << overload. The template itself is
kosher. The << overload not.
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: