Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #91514 > unrolled thread

What a bug

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2023-09-01 19:35 +0200
Last post2023-09-06 06:49 +0200
Articles 20 on this page of 48 — 10 participants

Back to article view | Back to comp.lang.c++


Contents

  What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-01 19:35 +0200
    Re: What a bug "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2023-09-01 23:09 +0200
      Re: What a bug "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-01 14:52 -0700
      Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-02 06:23 +0200
        Re: What a bug Muttley@dastardlyhq.com - 2023-09-02 10:25 +0000
          Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-02 12:56 +0200
            Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-02 14:35 +0200
              Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-02 14:41 +0200
            Re: What a bug Muttley@dastardlyhq.com - 2023-09-02 15:30 +0000
              Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-02 18:10 +0200
    Re: What a bug "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-01 14:50 -0700
      Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-02 06:19 +0200
        Re: What a bug "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-03 15:25 -0700
          Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-04 04:53 +0200
            Re: What a bug "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-03 20:01 -0700
              Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-04 06:59 +0200
                Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-04 11:11 +0200
              Re: What a bug "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-04 18:48 -0700
                Re: What a bug "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-14 16:27 -0700
          Re: What a bug scott@slp53.sl.home (Scott Lurndal) - 2023-09-04 14:24 +0000
            Re: What a bug "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-18 16:20 -0700
        Re: What a bug Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2023-09-04 18:43 -0400
          Re: What a bug red floyd <no.spam.here@its.invalid> - 2023-09-04 17:36 -0700
          Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-05 05:49 +0200
            Re: What a bug Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2023-09-06 12:00 -0400
              Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-06 19:46 +0200
                Re: What a bug Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2023-09-06 14:44 -0400
                  Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-07 04:51 +0200
                    Re: What a bug Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2023-09-06 23:54 -0400
                      Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-07 06:58 +0200
                        Re: What a bug Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2023-09-07 11:08 -0400
                          Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-07 17:56 +0200
                            Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-07 18:04 +0200
                              Re: What a bug Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2023-09-07 19:35 -0400
                          Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-07 17:46 +0200
    Re: What a bug jak <nospam@please.ty> - 2023-09-02 23:15 +0200
      Re: What a bug jak <nospam@please.ty> - 2023-09-03 23:17 +0200
        Re: What a bug Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-03 17:37 -0700
          Re: What a bug jak <nospam@please.ty> - 2023-09-05 11:01 +0200
            Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-05 11:12 +0200
            Re: What a bug Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-05 03:04 -0700
              Re: What a bug jak <nospam@please.ty> - 2023-09-07 01:18 +0200
                Re: What a bug James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-09-08 00:09 -0400
          Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-05 11:11 +0200
        Re: What a bug red floyd <no.spam.here@its.invalid> - 2023-09-05 20:53 -0700
          Re: What a bug Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-05 21:14 -0700
            Re: What a bug red floyd <no.spam.here@its.invalid> - 2023-09-06 17:51 -0700
          Re: What a bug Bonita Montero <Bonita.Montero@gmail.com> - 2023-09-06 06:49 +0200

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#91817

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2023-09-18 16:20 -0700
Message-ID<uealvc$206ck$1@dont-email.me>
In reply to#91536
On 9/4/2023 7:24 AM, Scott Lurndal wrote:
> "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
>> On 9/1/2023 9:19 PM, Bonita Montero wrote:
>>> Am 01.09.2023 um 23:50 schrieb Chris M. Thomasson:
>>>
>>>> Try something like:
>>>
>>> I know that I could have done that easier, but I wanted to know
>>> where's the bug and why my example does find the key value anyway.
>>>
>>>> ___________________________
>>>> #include <iostream>
>>>> #include <unordered_map>
>>>> #include <string>
>>>> #include <cstdlib>
>>>>
>>>>
>>>> int main()
>>>> {
>>>>       static std::unordered_map<std::string, long> opts = {
>>>>         {"--idle", 0 },
>>>>         {"--below", 1 },
>>>>         {"--above", 2 },
>>>>         {"--high", 3 },
>>>>         {"--realtime", 4 }
>>>>       };
>>>>
>>>>       auto mapped_opt = opts.find("--realtime");
>>>
>>> The problem here is that each find creates a string-object,
>>> which is rather slow.
>>
>> Right. Afaict, there is a way to create the strings on the stack and use
>> a little adapter logic to make it work with std::unordered_map. So, no
>> dynamic allocation.
> 
> Or just use getopt_long() with UTF-8 strings.

:^)

[toc] | [prev] | [next] | [standalone]


#91537

FromPavel <pauldontspamtolk@removeyourself.dontspam.yahoo>
Date2023-09-04 18:43 -0400
Message-ID<U4tJM.421219$Fgta.289098@fx10.iad>
In reply to#91518
Bonita Montero wrote:
> Am 01.09.2023 um 23:50 schrieb Chris M. Thomasson:
> 
>> Try something like:
> 
> I know that I could have done that easier, but I wanted to know
> where's the bug and why my example does find the key value anyway.
> 
>> ___________________________
>> #include <iostream>
>> #include <unordered_map>
>> #include <string>
>> #include <cstdlib>
>>
>>
>> int main()
>> {
>>      static std::unordered_map<std::string, long> opts = {
>>        {"--idle", 0 },
>>        {"--below", 1 },
>>        {"--above", 2 },
>>        {"--high", 3 },
>>        {"--realtime", 4 }
>>      };
>>
>>      auto mapped_opt = opts.find("--realtime");
> 
> The problem here is that each find creates a string-object,
> which is rather slow.

If you cared about the speed, why did you use unordered_map?

[toc] | [prev] | [next] | [standalone]


#91538

Fromred floyd <no.spam.here@its.invalid>
Date2023-09-04 17:36 -0700
Message-ID<ud5t77$1m72s$1@redfloyd.dont-email.me>
In reply to#91537
On 9/4/2023 3:43 PM, Pavel wrote:
> Bonita Montero wrote:
>> Am 01.09.2023 um 23:50 schrieb Chris M. Thomasson:
>>
>>> Try something like:
>>
>> I know that I could have done that easier, but I wanted to know
>> where's the bug and why my example does find the key value anyway.
>>
>>> ___________________________
>>> #include <iostream>
>>> #include <unordered_map>
>>> #include <string>
>>> #include <cstdlib>
>>>
>>>
>>> int main()
>>> {
>>>      static std::unordered_map<std::string, long> opts = {
>>>        {"--idle", 0 },
>>>        {"--below", 1 },
>>>        {"--above", 2 },
>>>        {"--high", 3 },
>>>        {"--realtime", 4 }
>>>      };
>>>
>>>      auto mapped_opt = opts.find("--realtime");
>>
>> The problem here is that each find creates a string-object,
>> which is rather slow.
> 
> If you cared about the speed, why did you use unordered_map?
> 

Yeah.  For something done exactly once, with 5 entries, best bet is a
std::array.

[toc] | [prev] | [next] | [standalone]


#91540

FromBonita Montero <Bonita.Montero@gmail.com>
Date2023-09-05 05:49 +0200
Message-ID<ud68h1$1r8t7$1@dont-email.me>
In reply to#91537
Am 05.09.2023 um 00:43 schrieb Pavel:

> If you cared about the speed, why did you use unordered_map?

My original example wasn't about speed. And the map is static, so it's
initialized thread-safe on the first run. But if I store strings in the
map, a string object is created with every lookup with a string literal,
which may result in a memory allocation. Depending on the case, this may
be too slow.

[toc] | [prev] | [next] | [standalone]


#91548

FromPavel <pauldontspamtolk@removeyourself.dontspam.yahoo>
Date2023-09-06 12:00 -0400
Message-ID<rm1KM.1058416$TPw2.302579@fx17.iad>
In reply to#91540
Bonita Montero wrote:
> Am 05.09.2023 um 00:43 schrieb Pavel:
> 
>> If you cared about the speed, why did you use unordered_map?
> 
> My original example wasn't about speed. And the map is static, so it's
> initialized thread-safe on the first run. But if I store strings in the
> map, a string object is created with every lookup with a string literal,
It does not have to be created since C++ 20.

> which may result in a memory allocation. Depending on the case, this may
> be too slow.

[toc] | [prev] | [next] | [standalone]


#91549

FromBonita Montero <Bonita.Montero@gmail.com>
Date2023-09-06 19:46 +0200
Message-ID<udadtj$2jf1f$1@dont-email.me>
In reply to#91548
Am 06.09.2023 um 18:00 schrieb Pavel:

> Bonita Montero wrote:

>> My original example wasn't about speed. And the map is static, so it's
>> initialized thread-safe on the first run. But if I store strings in the
>> map, a string object is created with every lookup with a string literal,

> It does not have to be created since C++ 20.

The string-object is created for every lookup with a string-literal
if the key is also a string-object. That has nothing to do with C++20.
The thread-safe initialization of the map, which is usually done with
double-checked locking, is guaranteed since C++11.

[toc] | [prev] | [next] | [standalone]


#91551

FromPavel <pauldontspamtolk@removeyourself.dontspam.yahoo>
Date2023-09-06 14:44 -0400
Message-ID<FM3KM.1257010$GMN3.837996@fx16.iad>
In reply to#91549
Bonita Montero wrote:
> Am 06.09.2023 um 18:00 schrieb Pavel:
> 
>> Bonita Montero wrote:
> 
>>> My original example wasn't about speed. And the map is static, so it's
>>> initialized thread-safe on the first run. But if I store strings in the
>>> map, a string object is created with every lookup with a string literal,
> 
>> It does not have to be created since C++ 20.
> 
> The string-object is created for every lookup with a string-literal
> if the key is also a string-object.
False. Read the standard.

> That has nothing to do with C++20.
False. Read the standard, e.g. how to use

template<class Key,
class T,
class Hash = hash<Key>,
class Pred = equal_to<Key>,
class Allocator = allocator<pair<const Key, T>>>
class unordered_map {
template<class K> iterator find(const K& k);
template<class K> const_iterator find(const K& k) const;
};

> The thread-safe initialization of the map, which is usually done with
> double-checked locking, is guaranteed since C++11.

[toc] | [prev] | [next] | [standalone]


#91558

FromBonita Montero <Bonita.Montero@gmail.com>
Date2023-09-07 04:51 +0200
Message-ID<udbdr2$2rk0p$1@dont-email.me>
In reply to#91551
Am 06.09.2023 um 20:44 schrieb Pavel:

> Bonita Montero wrote:

>> The string-object is created for every lookup with a string-literal
>> if the key is also a string-object.

> False. Read the standard.

Quote the standard.

>> That has nothing to do with C++20.

> False. Read the standard, e.g. how to use

Quote the standard.

> template<class Key,
> class T,
> class Hash = hash<Key>,
> class Pred = equal_to<Key>,
> class Allocator = allocator<pair<const Key, T>>>
> class unordered_map {
> template<class K> iterator find(const K& k);
> template<class K> const_iterator find(const K& k) const;
> };

Theres a templated K-parameter for the loookup, but internally
this parameter needs to be converted to a string-object to be
hashed and to be equality-comparable the same way.
In theory there might be overloaded specializations that take
a string_view or whatever; but that's ratther unlikely.

[toc] | [prev] | [next] | [standalone]


#91560

FromPavel <pauldontspamtolk@removeyourself.dontspam.yahoo>
Date2023-09-06 23:54 -0400
Message-ID<2QbKM.543979$Fgta.410052@fx10.iad>
In reply to#91558
Bonita Montero wrote:
> Am 06.09.2023 um 20:44 schrieb Pavel:
> 
>> Bonita Montero wrote:
> 
>>> The string-object is created for every lookup with a string-literal
>>> if the key is also a string-object.
> 
>> False. Read the standard.
> 
> Quote the standard.
> 
>>> That has nothing to do with C++20.
> 
>> False. Read the standard, e.g. how to use
> 
> Quote the standard.
> 
>> template<class Key,
>> class T,
>> class Hash = hash<Key>,
>> class Pred = equal_to<Key>,
>> class Allocator = allocator<pair<const Key, T>>>
>> class unordered_map {
>> template<class K> iterator find(const K& k);
>> template<class K> const_iterator find(const K& k) const;
>> };
> 
> Theres a templated K-parameter for the loookup, but internally
> this parameter needs to be converted to a string-object to be
> hashed and to be equality-comparable the same way.
correct

> In theory there might be overloaded specializations that take
> a string_view or whatever; 
not needed

> but that's ratther unlikely.
close but imprecise. That's simply not there.

[toc] | [prev] | [next] | [standalone]


#91563

FromBonita Montero <Bonita.Montero@gmail.com>
Date2023-09-07 06:58 +0200
Message-ID<udbla5$2sds6$1@dont-email.me>
In reply to#91560
Am 07.09.2023 um 05:54 schrieb Pavel:

>> In theory there might be overloaded specializations that take
>> a string_view or whatever; 

> not needed

With out such a specialization a string object needs to be created
inside find to have compatible hashing and equality comparison.

>> but that's ratther unlikely.

> close but imprecise. That's simply not there.

That's a theoretically valid possibility,
so it can't be said that it doesn't exist.

[toc] | [prev] | [next] | [standalone]


#91571

FromPavel <pauldontspamtolk@removeyourself.dontspam.yahoo>
Date2023-09-07 11:08 -0400
Message-ID<qHlKM.1326052$GMN3.523782@fx16.iad>
In reply to#91563
Bonita Montero wrote:
> Am 07.09.2023 um 05:54 schrieb Pavel:
> 
>>> In theory there might be overloaded specializations that take
>>> a string_view or whatever; 
> 
>> not needed
> 
> With out such a specialization a string object needs to be created
> inside find to have compatible hashing and equality comparison.

Not true. I was benevolently trying to make you read the standard so you 
could become a better C++ programmer but you refused.

I am therefore giving up on helping you. I will become evil and post the 
complete standard-compliant example that demonstrates how exactly the 
unordered_map::find can be made work on string literal and the map with 
the string keys without creating a string object (in the example, the 
string is wrapped in StringKey to track constructions easily but you are 
welcome to remove the wrapper). The code will work as described under 
C++20 but not any previous version of the standard -- and this is the 
expected behavior.

You still have a chance to improve your C++ programming skills if you 
read the standard and find the explanation for why this code shall 
behave like it does.

// ------------- code begin cut here -------------------------
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <numeric>
#include <string>
#include <unordered_map>

using namespace std;

class StringKey {like
public:
   StringKey(const char* cStr): s_(cStr) {
     cout << "\n\t(StringKey(" << cStr << ") called)\n";
   }
   const string& getS() const { return s_; }
private:
   string s_;
};

struct StringKeyHash {
   typedef void is_transparent;
   size_t operator()(const char *s) const {
     assert(!!s);
     return Hash(s, s + strlen(s));
   }
   size_t operator()(const StringKey &s) const {
     return Hash(s.getS().data(), s.getS().data() + s.getS().size());
   }
private:
   static size_t Hash(const char* begin, const char* end) {
     return accumulate(begin, end, (size_t) 0u,
         [](size_t a, char c) -> size_t { return a + (size_t)c; });
   }
};

struct StringKeyEq {
   typedef void is_transparent;
   bool operator()(const StringKey& x, const StringKey& y) const {
     return IsEq(x.getS().c_str(), y.getS().c_str());
   }
   bool operator()(const StringKey& x, const char* y) const {
     assert(!!y);
     return IsEq(x.getS().c_str(), y);
   }
   bool operator()(const char* x, const StringKey& y) const {
     assert(!!x);
     return IsEq(x, y.getS().c_str());
   }
private:
   static bool IsEq(const char *x, const char *y) {
     assert(!!x);
     assert(!!y);
     for (;; ++x, ++y) {
       if (*x == *y) {
         if (!*x)
           return true;
         continue;
       }
       assert(*x != *y);
       return false;
     }
   }
};

int
main(int, char*[]) {
   cout << "*** fill up the unordered map\n";
   unordered_map<StringKey, string, StringKeyHash, StringKeyEq> um {
     { "key1", "val1" },
     { "key2", "val2" },
   };
   const char* key3 = "key3";
   const char* key4 = "key4";
   const char* key1 = "key1";
   cout << "*** now do the the find\n";
   const auto i1 = um.find(key1);
   const bool r1 = i1 == um.end();
   const auto i3 = um.find(key3);
   const bool r3 = i3 == um.end();
   const auto i4 = um.find(key4);
   const bool r4 = i4 == um.end();
   cout << "find(" << key1 << "):" << r1 << ' ' <<
     "find(" << key4 << "):" << r4 << ' ' <<
     "find(" << key3 << "):" << r3 << endl;

   return 0;
}

// ------------- code end cut here -------------------------

// --- example run output if compiled by g++ -std=c++20 begin ---
$ ./a.out
*** fill up the unordered map

	(StringKey(key1) called)

	(StringKey(key2) called)
*** now do the the find
find(key1):0 find(key4):1 find(key3):1
// --- example run output if compiled by g++ -std=c++20 end ---

// --- example run output if compiled by g++ -std=c++17 begin ---
$ ./a.out
*** fill up the unordered map

	(StringKey(key1) called)

	(StringKey(key2) called)
*** now do the the find

	(StringKey(key1) called)

	(StringKey(key3) called)

	(StringKey(key4) called)
find(key1):0 find(key4):1 find(key3):1
// --- example run output if compiled by g++ -std=c++17 end ---


> 
>>> but that's ratther unlikely.
> 
>> close but imprecise. That's simply not there.
> 
> That's a theoretically valid possibility,
> so it can't be said that it doesn't exist.
This is "theoretically valid" only for those who refuse to read the 
standard; the others know the specialization is not there.

[toc] | [prev] | [next] | [standalone]


#91573

FromBonita Montero <Bonita.Montero@gmail.com>
Date2023-09-07 17:56 +0200
Message-ID<udcrqf$31mqp$3@dont-email.me>
In reply to#91571
Am 07.09.2023 um 17:08 schrieb Pavel:

 > Not true. I was benevolently trying to make you read the standard
 > so you  could become a better C++ programmer but you refused.

You're making a total differnt discussion and don't notce where's my
point. Within find for a string key a string key is generated from K
if the key is a string-object; that's all. What's wrong with that ?
The alternative you're showing below is sth. completely different
and the idea came across my mind when I discovered what's the problem
with my bug. But a string_view could much more performant if you won't
do any additional allocations per inserted node.
But that's not my point. Should I disable just my code debugging with
MSVC and show you the code which converts a string-pointer to a com-
pararable string-object ?

Rest unread.
Idiot !

[toc] | [prev] | [next] | [standalone]


#91574

FromBonita Montero <Bonita.Montero@gmail.com>
Date2023-09-07 18:04 +0200
Message-ID<udcsaj$31mqp$4@dont-email.me>
In reply to#91573
Am 07.09.2023 um 17:56 schrieb Bonita Montero:

> You're making a total differnt discussion and don't notce where's my
> point. Within find for a string key a string key is generated from K
> if the key is a string-object; that's all. What's wrong with that ?

Here are the declarations for C++20 from en.cppreference.com:

template< class K >
iterator find( const K& x );
	(3) 	(since C++20)
template< class K >
const_iterator find( const K& x ) const;
	(4) 	(since C++20)

MSVC hasn't code for that even I use C++20. I think MS dropped
that because an internal conversion within find() could be also
done externally while calling find(). Smart decision.

[toc] | [prev] | [next] | [standalone]


#91588

FromPavel <pauldontspamtolk@removeyourself.dontspam.yahoo>
Date2023-09-07 19:35 -0400
Message-ID<x7tKM.758940$qnnb.72202@fx11.iad>
In reply to#91574
Bonita Montero wrote:
> Am 07.09.2023 um 17:56 schrieb Bonita Montero:
> 
>> You're making a total differnt discussion and don't notce where's my
>> point. Within find for a string key
what is a "find for a string key"? Earlier you referred to a "lookup 
with a string-literal" which is what this discussion is about.

> a string key is generated from K
>> if the key is a string-object; that's all. What's wrong with that ?
> 
> Here are the declarations for C++20 from en.cppreference.com:
> 
> template< class K >
> iterator find( const K& x );
>      (3)     (since C++20)
> template< class K >
> const_iterator find( const K& x ) const;
>      (4)     (since C++20)
> 
> MSVC hasn't code for that even I use C++20. I think MS dropped
> that because an internal conversion within find()
What "internal conversion" within find() do you refer to? What is the 
source type? What is the destination type?

> could be also
> done externally while calling find(). Smart decision. 
No, just a defect. Not including the template version of find() is 
non-compliant with C++20 because it is affects for C++ programs. As a 
simple example, it makes a valid C++20 program fail to compile if that 
program calls one of unordered_map::find templates with the explicitly 
specified template parameter type.

[toc] | [prev] | [next] | [standalone]


#91590

FromBonita Montero <Bonita.Montero@gmail.com>
Date2023-09-07 17:46 +0200
Message-ID<udcr9g$31mqp$1@dont-email.me>
In reply to#91571
Am 07.09.2023 um 17:08 schrieb Pavel:

> Not true. I was benevolently trying to make you read the standard
> so you  could become a better C++ programmer but you refused.

You're making a total differnt discussion and don't notce where's my
point. Within find for a string key a string key is generated from K
if the key is a string-object; that's all. What's wrong with that ?
The alternative you're showing below is sth. completely different
and the idea came across my mind when I discovered what's the problem
with my bug. But a string_view could much more performant if you won't
do any additional allocations per inserted node.
But that's not my point. Should I disable just my code debugging with
MSVC and show you the code which converts a string-pointer to a com-
pararable string-object ?

Rest unread.
Idiot !

[toc] | [prev] | [next] | [standalone]


#91526

Fromjak <nospam@please.ty>
Date2023-09-02 23:15 +0200
Message-ID<ud08l2$i4aq$1@dont-email.me>
In reply to#91514
Bonita Montero ha scritto:
> I checked for some commandline options and I thought it would be the
> best to map that through an unordered_map. I extracted this from my
> application in the below code.
> 
> #include <Windows.h>
> #include <iostream>
> #include <variant>
> #include <unordered_map>
> 
> using namespace std;
> 
> int wmain( int argc, wchar_t **argv )
> {
>      static unordered_map<wchar_t const *, DWORD>
>          const opts =
>      {
>          { L"--idle", IDLE_PRIORITY_CLASS },
>          { L"--below", BELOW_NORMAL_PRIORITY_CLASS },
>          { L"--above", ABOVE_NORMAL_PRIORITY_CLASS },
>          { L"--high", HIGH_PRIORITY_CLASS },
>          { L"--realtime", REALTIME_PRIORITY_CLASS }
>      };
>      auto mappedPrio = opts.find( "--high" );
>      if( mappedPrio == opts.end() )
>          return -1;
>      return 0;
> }
> 
> Why does my code have a bug and why doesn't mappedPrio
> point to end() at the end?

HI,
you just need to use wchar_t in your search string as well:

from:
auto mappedPrio = opts.find( "--high" );
to:
auto mappedPrio = opts.find( L"--high" );

[toc] | [prev] | [next] | [standalone]


#91527

Fromjak <nospam@please.ty>
Date2023-09-03 23:17 +0200
Message-ID<ud2t4q$12vk6$1@dont-email.me>
In reply to#91526
jak ha scritto:
> Bonita Montero ha scritto:
>> I checked for some commandline options and I thought it would be the
>> best to map that through an unordered_map. I extracted this from my
>> application in the below code.
>>
>> #include <Windows.h>
>> #include <iostream>
>> #include <variant>
>> #include <unordered_map>
>>
>> using namespace std;
>>
>> int wmain( int argc, wchar_t **argv )
>> {
>>      static unordered_map<wchar_t const *, DWORD>
>>          const opts =
>>      {
>>          { L"--idle", IDLE_PRIORITY_CLASS },
>>          { L"--below", BELOW_NORMAL_PRIORITY_CLASS },
>>          { L"--above", ABOVE_NORMAL_PRIORITY_CLASS },
>>          { L"--high", HIGH_PRIORITY_CLASS },
>>          { L"--realtime", REALTIME_PRIORITY_CLASS }
>>      };
>>      auto mappedPrio = opts.find( "--high" );
>>      if( mappedPrio == opts.end() )
>>          return -1;
>>      return 0;
>> }
>>
>> Why does my code have a bug and why doesn't mappedPrio
>> point to end() at the end?
> 
> HI,
> you just need to use wchar_t in your search string as well:
> 
> from:
> auto mappedPrio = opts.find( "--high" );
> to:
> auto mappedPrio = opts.find( L"--high" );
> 
> 

mmm. This only works because the compiler uses the same area of memory
as the strings are equal and therefore compares a pointer to itself when
it finds the string. In fact if I replace this:

auto mappedPrio = opts.find( L"--high" );

with this other:

wchar_t what[] =  L"--high";
auto mappedPrio = opts.find( what );

the search fails.

I find this sneaky. In my opinion the compiler shouldn't treat two
objects as the same just because they have the same content.

[toc] | [prev] | [next] | [standalone]


#91529

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2023-09-03 17:37 -0700
Message-ID<87pm2y6af4.fsf@nosuchdomain.example.com>
In reply to#91527
jak <nospam@please.ty> writes:
> jak ha scritto:
>> Bonita Montero ha scritto:
>>> I checked for some commandline options and I thought it would be the
>>> best to map that through an unordered_map. I extracted this from my
>>> application in the below code.
>>>
>>> #include <Windows.h>
>>> #include <iostream>
>>> #include <variant>
>>> #include <unordered_map>
>>>
>>> using namespace std;
>>>
>>> int wmain( int argc, wchar_t **argv )
>>> {
>>>      static unordered_map<wchar_t const *, DWORD>
>>>          const opts =
>>>      {
>>>          { L"--idle", IDLE_PRIORITY_CLASS },
>>>          { L"--below", BELOW_NORMAL_PRIORITY_CLASS },
>>>          { L"--above", ABOVE_NORMAL_PRIORITY_CLASS },
>>>          { L"--high", HIGH_PRIORITY_CLASS },
>>>          { L"--realtime", REALTIME_PRIORITY_CLASS }
>>>      };
>>>      auto mappedPrio = opts.find( "--high" );
>>>      if( mappedPrio == opts.end() )
>>>          return -1;
>>>      return 0;
>>> }
>>>
>>> Why does my code have a bug and why doesn't mappedPrio
>>> point to end() at the end?
>> HI,
>> you just need to use wchar_t in your search string as well:
>> from:
>> auto mappedPrio = opts.find( "--high" );
>> to:
>> auto mappedPrio = opts.find( L"--high" );
>> 
>
> mmm. This only works because the compiler uses the same area of memory
> as the strings are equal and therefore compares a pointer to itself when
> it finds the string. In fact if I replace this:
>
> auto mappedPrio = opts.find( L"--high" );
>
> with this other:
>
> wchar_t what[] =  L"--high";
> auto mappedPrio = opts.find( what );
>
> the search fails.
>
> I find this sneaky. In my opinion the compiler shouldn't treat two
> objects as the same just because they have the same content.

The find() function of unordered_map<> compares keys for *equality*.

Since the code defines the key type as `wchar_t const *`, it does
pointer comparison, which has all the usual problems when you apply it
to string literals; L"foo" and L"foo" may or may not be stored at the
same memory location, and L"foo" and a string L"foo" derived from user
input will certainly not have the same address.

You can specify an equality function if you like.

A far simpler solution is to use std::wstring as the key type.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#91541

Fromjak <nospam@please.ty>
Date2023-09-05 11:01 +0200
Message-ID<ud6qom$1tniq$1@dont-email.me>
In reply to#91529
Keith Thompson ha scritto:
> jak <nospam@please.ty> writes:
>> jak ha scritto:
>>> Bonita Montero ha scritto:
>>>> I checked for some commandline options and I thought it would be the
>>>> best to map that through an unordered_map. I extracted this from my
>>>> application in the below code.
>>>>
>>>> #include <Windows.h>
>>>> #include <iostream>
>>>> #include <variant>
>>>> #include <unordered_map>
>>>>
>>>> using namespace std;
>>>>
>>>> int wmain( int argc, wchar_t **argv )
>>>> {
>>>>       static unordered_map<wchar_t const *, DWORD>
>>>>           const opts =
>>>>       {
>>>>           { L"--idle", IDLE_PRIORITY_CLASS },
>>>>           { L"--below", BELOW_NORMAL_PRIORITY_CLASS },
>>>>           { L"--above", ABOVE_NORMAL_PRIORITY_CLASS },
>>>>           { L"--high", HIGH_PRIORITY_CLASS },
>>>>           { L"--realtime", REALTIME_PRIORITY_CLASS }
>>>>       };
>>>>       auto mappedPrio = opts.find( "--high" );
>>>>       if( mappedPrio == opts.end() )
>>>>           return -1;
>>>>       return 0;
>>>> }
>>>>
>>>> Why does my code have a bug and why doesn't mappedPrio
>>>> point to end() at the end?
>>> HI,
>>> you just need to use wchar_t in your search string as well:
>>> from:
>>> auto mappedPrio = opts.find( "--high" );
>>> to:
>>> auto mappedPrio = opts.find( L"--high" );
>>>
>>
>> mmm. This only works because the compiler uses the same area of memory
>> as the strings are equal and therefore compares a pointer to itself when
>> it finds the string. In fact if I replace this:
>>
>> auto mappedPrio = opts.find( L"--high" );
>>
>> with this other:
>>
>> wchar_t what[] =  L"--high";
>> auto mappedPrio = opts.find( what );
>>
>> the search fails.
>>
>> I find this sneaky. In my opinion the compiler shouldn't treat two
>> objects as the same just because they have the same content.
> 
> The find() function of unordered_map<> compares keys for *equality*.
> 
> Since the code defines the key type as `wchar_t const *`, it does
> pointer comparison, which has all the usual problems when you apply it
> to string literals; L"foo" and L"foo" may or may not be stored at the
> same memory location, and L"foo" and a string L"foo" derived from user
> input will certainly not have the same address.
> 
> You can specify an equality function if you like.
> 
> A far simpler solution is to use std::wstring as the key type.
> 

HI,
I probably expressed myself badly. I agree with what you answered and
everything is clear to me. What I am contesting is the part where you
say "...may or may not be stored at the same memory location" because
that would mean that a program like this:

#include <iostream>

int main()
{
     auto eif = [] (bool t) {
         std::cout << ( t ? "equal" : "not equal" ) << std::endl;
     };

     char const *sp = "hello";
     char sl[] = "hello";

     eif( sp == sp );

     eif( "hello" == sp );

     eif( "hello" == "hello" );

     eif( "hello" == sl );

     return 0;
}

which has this as a result:

equal
equal
equal
not equal

could give different results depending on how the compiler acts when
deciding where to store strings (because here we are comparing
pointers). I simply think that different objects shouldn't be lumped
together just because they contain the same things, otherwise I would
have declared a single string and would have used its pointer around the
code. Pointers are for that too. it is my opinion that the program I
posted should have this as a result:

equal
not equal
not equal
not equal

[toc] | [prev] | [next] | [standalone]


#91543

FromBonita Montero <Bonita.Montero@gmail.com>
Date2023-09-05 11:12 +0200
Message-ID<ud6rep$1tq9a$2@dont-email.me>
In reply to#91541
Am 05.09.2023 um 11:01 schrieb jak:
> Keith Thompson ha scritto:
>> jak <nospam@please.ty> writes:
>>> jak ha scritto:
>>>> Bonita Montero ha scritto:
>>>>> I checked for some commandline options and I thought it would be the
>>>>> best to map that through an unordered_map. I extracted this from my
>>>>> application in the below code.
>>>>>
>>>>> #include <Windows.h>
>>>>> #include <iostream>
>>>>> #include <variant>
>>>>> #include <unordered_map>
>>>>>
>>>>> using namespace std;
>>>>>
>>>>> int wmain( int argc, wchar_t **argv )
>>>>> {
>>>>>       static unordered_map<wchar_t const *, DWORD>
>>>>>           const opts =
>>>>>       {
>>>>>           { L"--idle", IDLE_PRIORITY_CLASS },
>>>>>           { L"--below", BELOW_NORMAL_PRIORITY_CLASS },
>>>>>           { L"--above", ABOVE_NORMAL_PRIORITY_CLASS },
>>>>>           { L"--high", HIGH_PRIORITY_CLASS },
>>>>>           { L"--realtime", REALTIME_PRIORITY_CLASS }
>>>>>       };
>>>>>       auto mappedPrio = opts.find( "--high" );
>>>>>       if( mappedPrio == opts.end() )
>>>>>           return -1;
>>>>>       return 0;
>>>>> }
>>>>>
>>>>> Why does my code have a bug and why doesn't mappedPrio
>>>>> point to end() at the end?
>>>> HI,
>>>> you just need to use wchar_t in your search string as well:
>>>> from:
>>>> auto mappedPrio = opts.find( "--high" );
>>>> to:
>>>> auto mappedPrio = opts.find( L"--high" );
>>>>
>>>
>>> mmm. This only works because the compiler uses the same area of memory
>>> as the strings are equal and therefore compares a pointer to itself when
>>> it finds the string. In fact if I replace this:
>>>
>>> auto mappedPrio = opts.find( L"--high" );
>>>
>>> with this other:
>>>
>>> wchar_t what[] =  L"--high";
>>> auto mappedPrio = opts.find( what );
>>>
>>> the search fails.
>>>
>>> I find this sneaky. In my opinion the compiler shouldn't treat two
>>> objects as the same just because they have the same content.
>>
>> The find() function of unordered_map<> compares keys for *equality*.
>>
>> Since the code defines the key type as `wchar_t const *`, it does
>> pointer comparison, which has all the usual problems when you apply it
>> to string literals; L"foo" and L"foo" may or may not be stored at the
>> same memory location, and L"foo" and a string L"foo" derived from user
>> input will certainly not have the same address.
>>
>> You can specify an equality function if you like.
>>
>> A far simpler solution is to use std::wstring as the key type.
>>
> 
> HI,
> I probably expressed myself badly. I agree with what you answered and
> everything is clear to me. What I am contesting is the part where you
> say "...may or may not be stored at the same memory location" because
> that would mean that a program like this:
> 
> #include <iostream>
> 
> int main()
> {
>      auto eif = [] (bool t) {
>          std::cout << ( t ? "equal" : "not equal" ) << std::endl;
>      };
> 
>      char const *sp = "hello";
>      char sl[] = "hello";

Try to make s1 static const, then it may be joined.

> 
>      eif( sp == sp );
> 
>      eif( "hello" == sp );
> 
>      eif( "hello" == "hello" );
> 
>      eif( "hello" == sl );
> 
>      return 0;
> }
> 
> which has this as a result:
> 
> equal
> equal
> equal
> not equal
> 
> could give different results depending on how the compiler acts when
> deciding where to store strings (because here we are comparing
> pointers). I simply think that different objects shouldn't be lumped
> together just because they contain the same things, otherwise I would
> have declared a single string and would have used its pointer around the
> code. Pointers are for that too. it is my opinion that the program I
> posted should have this as a result:
> 
> equal
> not equal
> not equal
> not equal

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.c++


csiph-web