Path: csiph.com!weretis.net!feeder8.news.weretis.net!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c++ Subject: Re: What a bug Date: Sun, 03 Sep 2023 17:37:19 -0700 Organization: None to speak of Lines: 73 Message-ID: <87pm2y6af4.fsf@nosuchdomain.example.com> References: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: dont-email.me; posting-host="2d5fff03b065922503ffa3043f03177b"; logging-data="1195771"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18gnheifAMF0t0Lr8SjbToM" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:U21Cy0ZoVR4JCI2tzLLPzclRGew= sha1:7HxA75avs1jhAMDYWC3LcEgCpT0= Xref: csiph.com comp.lang.c++:91529 jak 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 >>> #include >>> #include >>> #include >>> >>> using namespace std; >>> >>> int wmain( int argc, wchar_t **argv ) >>> { >>>      static unordered_map >>>          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 */