Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #91514 > unrolled thread
| Started by | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| First post | 2023-09-01 19:35 +0200 |
| Last post | 2023-09-06 06:49 +0200 |
| Articles | 20 on this page of 48 — 10 participants |
Back to article view | Back to comp.lang.c++
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 →
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2023-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]
| From | Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> |
|---|---|
| Date | 2023-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]
| From | red floyd <no.spam.here@its.invalid> |
|---|---|
| Date | 2023-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2023-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]
| From | Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> |
|---|---|
| Date | 2023-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2023-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]
| From | Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> |
|---|---|
| Date | 2023-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2023-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]
| From | Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> |
|---|---|
| Date | 2023-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2023-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]
| From | Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> |
|---|---|
| Date | 2023-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2023-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2023-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]
| From | Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> |
|---|---|
| Date | 2023-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2023-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]
| From | jak <nospam@please.ty> |
|---|---|
| Date | 2023-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]
| From | jak <nospam@please.ty> |
|---|---|
| Date | 2023-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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2023-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]
| From | jak <nospam@please.ty> |
|---|---|
| Date | 2023-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2023-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