Saturday, September 21, 2019

Digest for comp.lang.c++@googlegroups.com - 16 updates in 5 topics

Bonita Montero <Bonita.Montero@gmail.com>: Sep 21 06:07PM +0200

Can anyone tell me why hash<size_t> or even all hash<>-specializations
for integral values my platform return not the value itself as the hash
-code? That doesn't make sense to me because if you have n different
input-values for the hash-generators you would have maximally have n
different output values (if the integral type is less or equal in size
than size_t, which is usually true on 64-bit-platforms); or even more:
when you hash an integral value with maximally the size of a size_t
you might even get collisions depending on the hash-algorithm whereas
with 1:1-mapping wont get any collisions.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 21 06:59PM +0200

Ok, that's only the standard-library of MSVC that
handles it in this way. Consider the following code:
 
#include <iostream>
#include <functional>
 
using namespace std;
 
int main()
{
hash<size_t> hasher;
size_t hash = hasher( 123 );
cout << hash << endl;
}
 
"MSVC" ouptputs: 10276731894227909406
glibc++ is so reasonable as to simply output: 123.
Juha Nieminen <nospam@thanks.invalid>: Sep 21 05:29PM

> when you hash an integral value with maximally the size of a size_t
> you might even get collisions depending on the hash-algorithm whereas
> with 1:1-mapping wont get any collisions.
 
You have a misconception there.
 
The situation is exactly the opposite: Using the integer value itself
as its hash is actually an extremely *poor* hashing function, not
the "optimal" one.
 
It would optimal if the hash table had as many buckets as the maximum
value of the integer (ie. eg. 2^32 in the case of 32-bit integers).
However, that's not feasible in the least. The typical number of buckets
in a hash table is very small (in relation to the maximum value of the
key), and you want to distribute elements *as randomly as possible*
into them. Using the key itself as the hash value is extremely poor
randomness with a significantly smaller amount of buckets than the
maximum key value, and will usually cause an enormous amounts of
collisions.
 
The default hash functions for integral values in libstdc++ (used by
gcc) simply return the value itself, which is extremely bad. I assume
they do this because of pure laziness (or to avoid some kind of
controversy, as there is no universally agreed "best" hashing
function for integers).
Bonita Montero <Bonita.Montero@gmail.com>: Sep 21 07:37PM +0200

> The situation is exactly the opposite: Using the integer value itself
> as its hash is actually an extremely *poor* hashing function, not
> the "optimal" one.
 
No, when the integer-value has less or equal bits than the hash-value
a 1:1-mapping is a perfect solution. And the glibc++ behaves exactly
in this way.
 
> It would optimal if the hash table had as many buckets as the maximum
> value of the integer (ie. eg. 2^32 in the case of 32-bit integers).
 
The number of buckets in a hashtable is a different discussion.
 
> in a hash table is very small (in relation to the maximum value of the
> key), and you want to distribute elements *as randomly as possible*
> into them.
 
If you have n distinct values in the input-value and the input-value
more less bits in output-value, you would get a maxumum of n output
-values. So you could stick with a 1:1-mapping and discard the higher
bits not fitting in the hash-index. That's a perfect solution.
 
> The default hash functions for integral values in libstdc++ (used
> by gcc) simply return the value itself, which is extremely bad.
 
No, that's absolutely not bad.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 21 07:46PM +0200

> more less bits in output-value, you would get a maxumum of n output
> -values. So you could stick with a 1:1-mapping and discard the higher
> bits not fitting in the hash-index. That's a perfect solution.
 
And even more: you get a equal distribution on all buckets if all keys
are represented equally frequent.
Soviet_Mario <SovietMario@CCCP.MIR>: Sep 21 11:44AM +0200

On 20/09/2019 20:52, Paavo Helde wrote:
 
> I hoped that the line "using namespace
> std::literals::string_literals" would give a hint or at
> least provide something to google. But apparently not.
 
ah...okay, no did not even suspect such feature before
 
 
> Anyway, "abc"s is a std::string literal. You know, these are
> the kind of literals one should use in C++.
 
Good thing a native constant std::string !! I'll search
literals spread in code to replace with this new native type.
 
Uh another related question. When one uses a true string
literal "ABC"s to just intialize a variable string, instead
of a "ABC" char *, a more efficient code is generated ?
 
I mean, apart from the constness, these new literals are
identical types to std::string or
 
 
> The char*
> strings (and the problems with concatenating them) belong to
> another language which is supported for legacy only.
 
I understand this position, but thank God the back
compatibility is maintained. Quite some are still amidst the
transition and use C++ as just an improved C with classes
 
> If you
> just avoid using char* strings and literals your problem
> will disappear.
 
notice taken, I'll try to locate the more old style literals
I can to replace. And also the ugly .append () notation
 
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)
Soviet_Mario <SovietMario@CCCP.MIR>: Sep 21 11:50AM +0200

On 20/09/2019 21:03, Keith Thompson wrote:
>> return ""s + a + b;
>> }
 
> "..."s was added in C++14.
 
oh, I see ... installed QT reports C++11 if I'm not wrong.
Dunno if free upgrades are available (i have the free version)
 
On the system the installed compiler versions are :
 
GCC 6.3.0-18 and GCC 4:6.3.0-4 (I don't think QT ships a
compiler of its own in the free version)
 
 
> std::cout << std::string() + "hello" + ' ' + "world" + '\n';
> // OR
> std::cout << std::string("") + "hello" + ' ' + "world" + '\n';
 
I'll search the options to see if I can configure the
standard used
Thanks
 
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)
Melzzzzz <Melzzzzz@zzzzz.com>: Sep 21 03:03PM


> Uh another related question. When one uses a true string
> literal "ABC"s to just intialize a variable string, instead
> of a "ABC" char *, a more efficient code is generated ?
 
I guess, what's the point if not?
 
--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala
Paavo Helde <myfirstname@osa.pri.ee>: Sep 21 07:08PM +0300

On 21.09.2019 12:44, Soviet_Mario wrote:
 
> Uh another related question. When one uses a true string literal "ABC"s
> to just intialize a variable string, instead of a "ABC" char *, a more
> efficient code is generated ?
 
Why do you want to know? The difference, even if existing, would be
minuscule and most probably compiler, platform and optimization level
dependent. You should not take such concerns into account when choosing
how to write your code.
 
Anyway, initializing a std::string variable directly by a std::string
literal avoids one conversion involving one strlen() call, at least
conceptually, so my wild guess is it should be as fast as or faster than
using a char* literal.
David Brown <david.brown@hesbynett.no>: Sep 21 07:07PM +0200

On 21/09/2019 11:50, Soviet_Mario wrote:
 
> On the system the installed compiler versions are :
 
> GCC 6.3.0-18  and  GCC 4:6.3.0-4  (I don't think QT ships a compiler of
> its own in the free version)
 
AFAIK QT never ships with any compiler, no matter what license you use.
It is entirely up to /you/ which compiler you use, and what settings you
pick for it, including the C++ standard to use.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 21 01:08PM +0200

> } \
> if (!(x)) __builtin_unreachable(); \
> } while (0)
 
This tells the compiler to verify if an expression has certain
constraints if it is constant. But in this case the compiler
does know the constraints on x itself so there wouldn't be any
need to have an additional assume like in MSVC. But __assume
with MSVC tells the compiler certain constaints it can't figure
out itself.
David Brown <david.brown@hesbynett.no>: Sep 21 07:05PM +0200

On 21/09/2019 13:08, Bonita Montero wrote:
> need to have an additional assume like in MSVC. But __assume
> with MSVC tells the compiler certain constaints it can't figure
> out itself.
 
Look more closely. (I already explained this.) If the expression has a
value known to the compiler, then the compiler should check if it is
false - in which case you have definitely got something wrong. You get
this, for example, if you write "assume(2 == 3);". The point is to
force a compile-time error in such cases, not just inform the compiler
and let it silently optimise the code.
 
Otherwise, it is the line "if (!(x)) __builtin_unreachable();" that is
critical. "__builtin_unreachable()" tells the compiler that the runtime
will never reach that point in the code. So the compiler knows that
!(x) cannot ever be true - i.e., (x) is always true.
 
Try it out, and you will see how it works.
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Sep 21 01:12AM -0600

On Fri, 20 Sep 2019 07:24:21 -0700 (PDT), Frederick Gotham
>}
 
>This will allow me to see if this function was called from a ***particular** function... and then I think I can use pthread functions to get the thread ID, and combine the two to see if the function should behave differently.
 
>thoughts?
 
My thoughts:
 
As Robert indicated, this might work ... sometimes.
 
If you were in the middle of a debugging session, then using backtrace
info to expose information about the call chain and to test hypotheses
could be a clever way to save yourself hours of work.
 
Depending on backtrace info in production code sounds like a good way
to land someone in an hours-long debugging session.
 
Don't do it.
 
Louis
queequeg@trust.no1 (Queequeg): Sep 21 01:57PM


> There's a function that must behave a little differently if it's called
> from a **particular** function in a **particular** thread.
 
With particular thread it's simple, just store thread ID and compare it
later. With function it gets tricky.
 
Can you edit the header included from the file that you cannot modify? If
yes, maybe instead of a function prototype, write a macro that will check
__FUNCTION__ variable, or just call your function (that you can modify)
with __FUNCTION__ as an argument.
 
Something like this:
 
#v+ test.cpp
#include <string>
#include <cstdio>
 
// prototype which you can modify (in header)
#define myFunction() myFunction2(__FUNCTION__)
 
// function that you can modify
void myFunction2(const std::string& functionName)
{
if (functionName == "main")
printf("Called from main\n");
else
printf("Not called from main, called from %s instead\n",
functionName.c_str());
}
 
// function that you cannot modify
void fn()
{
myFunction();
}
 
// function that you cannot modify
int main()
{
myFunction();
fn();
return 0;
}
#v-
 
--
https://www.youtube.com/watch?v=9lSzL1DqQn0
porparek@gmail.com: Sep 21 03:43AM -0700

On Sunday, September 15, 2019 at 1:22:24 PM UTC+2, Öö Tiib wrote:
 
> I guess you wanted to write here:
 
> template < typename T >
> concept Integral = std::is_integral<T>::value;
 
Thank all of you for answers.
Could you please give me some rules of when to use short form of a concept, like:
template < typename T >
concept Integral = std::is_integral<T>::value;
 
and when to use a longer one, like:
template < typename T >
concept bool Integral = requires ( T t ) {
{ std::is_integral<T>::value } -> bool;
};
 
I mean I have only 2 examples above and found others on the internet but I don't get the general rule.
Bo Persson <bo@bo-persson.se>: Sep 21 02:34PM +0200

> { std::is_integral<T>::value } -> bool;
> };
 
> I mean I have only 2 examples above and found others on the internet but I don't get the general rule.
 
The general rule is that the longer form is from the separate Concepts
TS (ISO Technical Specification), while the shorter form looks like what
made into the (still draft) C++20 language.
 
https://en.cppreference.com/w/cpp/experimental/constraints
https://en.cppreference.com/w/cpp/language/constraints
 
Then there is the problem of which version, if any, your compiler is
supposed to support. :-)
 
 
 
Bo Persson
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: