Monday, November 9, 2020

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

Tim Rentsch <tr.17687@z991.linuxsc.com>: Nov 08 11:17PM -0800

> a single instantiation).
 
> My context is C++11 or C++14; a C++17 or later solution would be
> interesting, but of no immediate use to me.
 
I believe C++17 (or C++20?) offers constructions sufficient to
accomplish this. However I don't think any of those ways are
available in C++14 or earlier.
 
If I had this problem to deal with, probably I would do something
like this:
 
#include <unordered_set>
#include <unordered_map>
 
#define CLASS_HASHER( KeyType ) \
namespace std { \
template <> struct hash< class KeyType > { \
\
using result_type = size_t; \
using argument_type = KeyType; \
\
result_type \
operator()( const KeyType &it ) const { \
return it.me_hash_function(); \
} \
\
}; \
}
 
struct Whatsit {
size_t blah;
size_t me_hash_function() const { return blah; }
};
 
CLASS_HASHER( Whatsit )
 
void
check_it_out(){
std::unordered_map< Whatsit, int > whatsits_values;
std::unordered_set< Whatsit > whatsits;
}
 
Of course the point of the CLASS_HASHER macro is that it can be
reused for any class that needs it. The overhead is then one
extra line of code per self-hashing class, which in my view
is acceptable.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Nov 09 08:37PM

On Mon, 2020-11-09, Tim Rentsch wrote:
> reused for any class that needs it. The overhead is then one
> extra line of code per self-hashing class, which in my view
> is acceptable.
 
Thanks. Yes, an extra line would be acceptable -- although I'm sure
people would find the macro odd, if they found it.
 
For now I've decided to use std::map and friends, unless I know I have
a performance problem. I'm a bit disappointed, because C++ doesn't
usually let me down. When things are hard to express well, I normally
understand why ... but I still don't understand why it's harder to use
a class with the unordered containers than with the ordered
equivalents.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 09:03AM +0100

>> Designated initializers aren't needed. There are constructors.
 
> Loops aren't needed. There are gotos.
 
That's an analogy in the opposite direction. Gotos are technically
less usable than loops. But constructors are more flexible than
designated initializers.
Juha Nieminen <nospam@thanks.invalid>: Nov 09 08:14AM

> Designated initializers aren't needed. There are constructors.
 
Show me how you do this with constructors:
 
struct S
{
int a = 1, b = 2, c = 3, d = 4, e = 5;
};
 
const S obj1 = { .b = 10, .d = 20 };
const S obj2 = { .d = 15, .e = 16 };
const S obj3 = { .a = 100, .c = 200, .e = 300 };
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 09:19AM +0100

> const S obj1 = { .b = 10, .d = 20 };
> const S obj2 = { .d = 15, .e = 16 };
> const S obj3 = { .a = 100, .c = 200, .e = 300 };
 
That's not possible and not needed.
But the default-values make a lot of confusion since
they can be scattered in the defininition of the struct.
So better use constructors.
Ian Collins <ian-news@hotmail.com>: Nov 09 09:29PM +1300

On 09/11/2020 21:19, Christian Hanné wrote:
>> const S obj2 = { .d = 15, .e = 16 };
>> const S obj3 = { .a = 100, .c = 200, .e = 300 };
 
> That's not possible and not needed.
 
Why not needed?
 
> But the default-values make a lot of confusion since
> they can be scattered in the defininition of the struct.
 
No, they don't.
 
> So better use constructors.
 
No, it isn't. If you need different members initialised in different
contexts, designated initialisers are your friend.
 
--
Ian.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Nov 09 12:39AM -0800


>> So better use constructors.
 
> No, it isn't. If you need different members initialised in different
> contexts, designated initialisers are your friend.
 
A while ago, Christian Hanné posted a lot of deliberate nonsense in
comp.lang.c. Don't expect reasonable replies.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 09:50AM +0100

>> So better use constructors.
 
> No, it isn't.  If you need different members initialised in different
> contexts, designated initialisers are your friend.
 
I said why this confuses the reader. With constructors you have
the declaration of the construtor in a tooltip in your IDE, with
designated initializers you have to check the structure definition
first.
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 09:50AM +0100

> A while ago, Christian Hanné posted a lot of deliberate
> nonsense in comp.lang.c. Don't expect reasonable replies.
 
I never posted nonsense.
Juha Nieminen <nospam@thanks.invalid>: Nov 09 11:46AM

> the declaration of the construtor in a tooltip in your IDE, with
> designated initializers you have to check the structure definition
> first.
 
Firstly, if understanding the code requires an IDE, then the code is badly
designed.
 
Secondly, if an IDE is able to show the constructor signature in a tooltip,
then certainly it can show the members of a struct in a designated
initalizer list? If not, and you rely so much on IDE tooltips, then get
a better IDE.
 
Thirdly, designated initializers make initialization a lot clearer
because they function, essentially, as named parameters, which is
something that constructors (and functions in general) have always lacked
in C++.
 
This is particularly handy for configuration headers and such, which may
be written and fine-tuned by team members other than the original programmer
(some of which may not be programmers at all). I have used this quite
extensively, to create "configuration" files like:
 
const Settings kSettings
{
.numberOfStuff = 123,
.aValueForSomething = 5,
.aFactorUsedForThis = 0.25,
 
.elements =
{
{ .amount = 5, .factor = 2.2, .seconds = 10 },
{ .amount = 8, .factor = 1.0, .seconds = 15 },
{ .amount = 1, .factor = 0.5, .seconds = 5 }
}
};
 
Even a complete non-coder can go and fine-tune those values without the
need to understand C++ (especially when the variables are named clearly
according to the context; obviously I used fictitious names above).
 
(In fact, I have used that technique quite a lot in some Objective-C++
programs, where the order of initialization doesn't need to match the
order of declaration. This is particularly handy because it allows the
initialization to use an ordering that's easy to read and understand,
while the declaration may use an ordering that's eg. optimized for
space, as the order of declaration of member variables matter in this
regard. It's a huge same that C++20 decided to put the limitation that
the initializers must be in the same order as the declaration.)
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 12:50PM +0100

> Firstly, if understanding the code requires an IDE, then the code is badly
> designed.
 
Wrong, an IDE has many facilities which can't be replaced by proper
coding.
 
> Secondly, if an IDE is able to show the constructor signature in a tooltip,
> then certainly it can show the members of a struct in a designated
> initalizer list? ...
 
Neither CLion, nor Visual Studio, nor Eclipse CDE can do this.
 
> because they function, essentially, as named parameters, which is
> something that constructors (and functions in general) have always
> lacked in C++.
 
Therefore you have an IDE.
 
Haven't read the rest of your nonsense.
Juha Nieminen <nospam@thanks.invalid>: Nov 09 02:32PM

> Haven't read the rest of your nonsense.
 
I'll take that as a concession of defeat. If you can't answer to the
arguments given to you, that's because you don't have an answer. You
don't have any valid counter-argument. Therefore you just concede.
The only thing you can do at that point is act in an arrogant and
dismissive manner. I suppose the insults will soon follow.
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 03:43PM +0100

> don't have any valid counter-argument. Therefore you just concede.
> The only thing you can do at that point is act in an arrogant and
> dismissive manner. I suppose the insults will soon follow.
 
Why do you argue so if you do it the same way by not responding to
what I said ?
Juha Nieminen <nospam@thanks.invalid>: Nov 09 03:41PM

>> dismissive manner. I suppose the insults will soon follow.
 
> Why do you argue so if you do it the same way by not responding to
> what I said ?
 
You didn't bother responding to all the arguments I made, but
you expect me to respond to all your arguments? Especially when
you have that kind of attitude?
 
Right.
scott@slp53.sl.home (Scott Lurndal): Nov 09 04:09PM

>don't have any valid counter-argument. Therefore you just concede.
>The only thing you can do at that point is act in an arrogant and
>dismissive manner. I suppose the insults will soon follow.
 
You are responding to Bonita (who, when slips and forgets to
delete the attribution headers, shows that Bonita uses a
German locale in its newsreader).
 
Note this Hanne fellow also removes attributions and makes stupid
arguments.
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 06:31PM +0100

> You are responding to Bonita (who, when slips and forgets to
> delete the attribution headers, shows that Bonita uses a
> German locale in its newsreader).
 
Sorry, but please stop with this imputations.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Nov 09 10:47AM -0800

> German locale in its newsreader).
 
> Note this Hanne fellow also removes attributions and makes stupid
> arguments.
 
I don't know whether Christian Hanné is a sockpuppet for Bonita
or not. And frankly it doesn't matter. I suggest we avoid wasting
time debating that particular point. (I personally will not waste
time responding to Christian Hanné at all.)
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
Jorgen Grahn <grahn+nntp@snipabacken.se>: Nov 09 08:24PM

On Sun, 2020-11-08, Christian Hanné wrote:
> Designated initializers aren't needed. There are constructors.
 
To my surprise, I agree. In fact, I thought everyone agreed on this,
and that that's why it wasn't squeezed into C++11.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
olcott <NoOne@NoWhere.com>: Nov 09 09:00AM -0600

This <is> the simplest concrete counter-example of all of the
conventional halting problem proofs.
 
void Halt_Fooler(u32 P)
{
if (Halts(P, P))
HALT
else
HERE: goto HERE;
}
 
I am dropping my reference to Linz because it only gets people confused.
 
The UTM Halts(u32 P, u32 I) (at least partial) halt decider executes the
x86 Turing machine Description of its input until it detects that:
 
(a) Its input would never terminate unless forced to terminate by this
(at least partial) halt decider.
 
(b) Its input has already halted on its own.
 
When-so-ever a halt decider correctly decides that its input would
never halt unless forced to halt by this halt decider this halt decider
has correctly detected an input that would not halt and can transition
to its final state of DOES_NOT_HALT.
 
This shows that H_HAT(H_HAT) does not halt when run on its own:
 
bool Aborted_Because_Non_Halting_Behavior_Detected(u32 P, u32 I)
{
bool Halted = false;
bool Aborted = false;
while (!Halted && !Aborted)
{
Halted = DebugStep(H_Hat, H_Hat);
// Aborted = Needs_To_Be_Aborted();
}
return Aborted;
}
 
void H_Hat(u32 P) // (bottom of page 319)
{
if (Aborted_Because_Non_Halting_Behavior_Detected(P, P))
HALT
else
HERE: goto HERE;
}
 
int main()
{
H_Hat(H_Hat);
 
calls bool Aborted_Because_Non_Halting_Behavior_Detected(H_Hat, H_Hat)
 
In the above case H_Hat(H_Hat) never terminates.
 
 
--
Copyright 2020 Pete Olcott
 
"Great spirits have always encountered violent opposition from mediocre
minds." Einstein
Tim Rentsch <tr.17687@z991.linuxsc.com>: Nov 08 11:03PM -0800

>> could be rearranged as suggested above is therefore not feasible.
 
> To be clear, this rule isn't (quite) stated explicitly, but it
> follows from the common initial sequence rule in N1570 6.5.2.3.
 
Right. There is no explicit rule, it is only a consequence of
other stated requirements.
 
> In principle I suppose a compiler could violate the rule in cases
> where it knows that there's no union containing a given structure
> as a member,
 
I think so, but it isn't easy to decide which sets of circumstances
would allow it. There may not be a union in this TU, but I think
there are cases where there is one in another TU that would prevent
an alternate choice from being conforming. It's a messy problem.
 
> but I can't think of any good reason to do so.
 
Me either. In practical terms I believe there is no viable
alternative.
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: