Boost C++ Libraries: Ticket #12919: multi_index indexed with hashed_non_unique produces buffer overrun. https://svn.boost.org/trac10/ticket/12919 <p> Using multi_index_container on a struct indexing using hashed_non_unique (hashing a std::string) can cause a buffer overrun in unchecked_rehash(size_type,hashed_non_unique_tag), typically culminating in a segfault. </p> <p> The segment below, taken from lines 1351-1372 of boost/multi_index/hash_index.hpp, can iterate between two different nodes, causing <code>x==end_</code> to never occur, causing a auto_space to be overrun, eventually leading to a segmentation fault. </p> <div class="wikipage" style="font-size: 80%"><p> Code highlighting: </p> <div class="wiki-code"><div class="code"><pre> <span class="n">auto_space</span><span class="o">&lt;</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="p">,</span><span class="n">allocator_type</span><span class="o">&gt;</span> <span class="n">hashes</span><span class="p">(</span><span class="n">get_allocator</span><span class="p">(),</span><span class="n">size</span><span class="p">());</span> <span class="n">auto_space</span><span class="o">&lt;</span> <span class="n">node_impl_pointer</span><span class="p">,</span><span class="n">allocator_type</span><span class="o">&gt;</span> <span class="n">node_ptrs</span><span class="p">(</span><span class="n">get_allocator</span><span class="p">(),</span><span class="n">size</span><span class="p">());</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="kt">bool</span> <span class="n">within_bucket</span><span class="o">=</span><span class="nb">false</span><span class="p">;</span> <span class="n">BOOST_TRY</span><span class="p">{</span> <span class="k">for</span><span class="p">(;;</span><span class="o">++</span><span class="n">i</span><span class="p">){</span> <span class="n">node_impl_pointer</span> <span class="n">x</span><span class="o">=</span><span class="n">end_</span><span class="o">-&gt;</span><span class="n">prior</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="n">x</span><span class="o">==</span><span class="n">end_</span><span class="p">)</span><span class="k">break</span><span class="p">;</span> <span class="cm">/* only this can possibly throw */</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">h</span><span class="o">=</span><span class="n">hash_</span><span class="p">(</span><span class="n">key</span><span class="p">(</span><span class="n">node_type</span><span class="o">::</span><span class="n">from_impl</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">()));</span> <span class="n">hashes</span><span class="p">.</span><span class="n">data</span><span class="p">()[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">h</span><span class="p">;</span> <span class="n">node_ptrs</span><span class="p">.</span><span class="n">data</span><span class="p">()[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">x</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">node_impl_pointer</span><span class="p">,</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">p</span><span class="o">=</span> <span class="n">node_alg</span><span class="o">::</span><span class="n">unlink_last_group</span><span class="p">(</span><span class="n">end_</span><span class="p">);</span> <span class="n">node_alg</span><span class="o">::</span><span class="n">link_range</span><span class="p">(</span> <span class="n">p</span><span class="p">.</span><span class="n">first</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">buckets_cpy</span><span class="p">.</span><span class="n">at</span><span class="p">(</span><span class="n">buckets_cpy</span><span class="p">.</span><span class="n">position</span><span class="p">(</span><span class="n">h</span><span class="p">)),</span><span class="n">cpy_end</span><span class="p">);</span> <span class="n">within_bucket</span><span class="o">=!</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">second</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </pre></div></div></div><p> The solution is quite simple, and is shown in the other implementation of unchecked_rehash(size_type,hashed_unique_tag), by ensuring the rehash does not exceed the number of elements. The proper implementation (possibly suboptimal) would look something like this: </p> <div class="wikipage" style="font-size: 80%"><p> Code highlighting: </p> <div class="wiki-code"><div class="code"><pre> <span class="n">auto_space</span><span class="o">&lt;</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="p">,</span><span class="n">allocator_type</span><span class="o">&gt;</span> <span class="n">hashes</span><span class="p">(</span><span class="n">get_allocator</span><span class="p">(),</span><span class="n">size</span><span class="p">());</span> <span class="n">auto_space</span><span class="o">&lt;</span> <span class="n">node_impl_pointer</span><span class="p">,</span><span class="n">allocator_type</span><span class="o">&gt;</span> <span class="n">node_ptrs</span><span class="p">(</span><span class="n">get_allocator</span><span class="p">(),</span><span class="n">size</span><span class="p">());</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">size_</span><span class="o">=</span><span class="n">size</span><span class="p">();</span> <span class="kt">bool</span> <span class="n">within_bucket</span><span class="o">=</span><span class="nb">false</span><span class="p">;</span> <span class="n">BOOST_TRY</span><span class="p">{</span> <span class="k">for</span><span class="p">(;</span><span class="n">i</span><span class="o">!=</span><span class="n">size_</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">){</span> <span class="n">node_impl_pointer</span> <span class="n">x</span><span class="o">=</span><span class="n">end_</span><span class="o">-&gt;</span><span class="n">prior</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="n">x</span><span class="o">==</span><span class="n">end_</span><span class="p">)</span><span class="k">break</span><span class="p">;</span> <span class="cm">/* only this can possibly throw */</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">h</span><span class="o">=</span><span class="n">hash_</span><span class="p">(</span><span class="n">key</span><span class="p">(</span><span class="n">node_type</span><span class="o">::</span><span class="n">from_impl</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">()));</span> <span class="n">hashes</span><span class="p">.</span><span class="n">data</span><span class="p">()[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">h</span><span class="p">;</span> <span class="n">node_ptrs</span><span class="p">.</span><span class="n">data</span><span class="p">()[</span><span class="n">i</span><span class="p">]</span><span class="o">=</span><span class="n">x</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">node_impl_pointer</span><span class="p">,</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">p</span><span class="o">=</span> <span class="n">node_alg</span><span class="o">::</span><span class="n">unlink_last_group</span><span class="p">(</span><span class="n">end_</span><span class="p">);</span> <span class="n">node_alg</span><span class="o">::</span><span class="n">link_range</span><span class="p">(</span> <span class="n">p</span><span class="p">.</span><span class="n">first</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">buckets_cpy</span><span class="p">.</span><span class="n">at</span><span class="p">(</span><span class="n">buckets_cpy</span><span class="p">.</span><span class="n">position</span><span class="p">(</span><span class="n">h</span><span class="p">)),</span><span class="n">cpy_end</span><span class="p">);</span> <span class="n">within_bucket</span><span class="o">=!</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">second</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </pre></div></div></div><p> As the data leading to this segfault is private, I currently do not have a minimal, verified example to reproduce the bug, however, I believe this is a rational explanation, with a straight-forward fix. </p> <p> I've seen examples where an ~800 element buffer will continue until i &gt; 15,000, culminating in a segfault. I will submit a pull request with the above diff. </p> <p> Thanks, Alex </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/12919 Trac 1.4.3 Alex Huszagh <ahuszagh@…> Mon, 20 Mar 2017 23:02:10 GMT attachment set https://svn.boost.org/trac10/ticket/12919 https://svn.boost.org/trac10/ticket/12919 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">hashed_index.patch</span> </li> </ul> <p> Diff between old and new for bug fix </p> Ticket Joaquín M López Muñoz Tue, 21 Mar 2017 08:41:15 GMT <link>https://svn.boost.org/trac10/ticket/12919#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12919#comment:1</guid> <description> <p> Hi Alex, </p> <p> Thank you for reporting the problem. I can't just accept your patch because, even f it worked, it would be masking a more serious problem, namely that erasing elements from a hashed index does not eventually lead to an empty structure where <code>end_-&gt;prior()==end_</code> --this is a fundamental property of the underyling data structure. So, I need to know more about the context where this is happening. I understand the data you work with is private, but could you at least show the hashing code for <code>std::string</code> you're using? I suspect there might be a problem with that. </p> </description> <category>Ticket</category> </item> <item> <author>Alex Huszagh <ahuszagh@…></author> <pubDate>Tue, 21 Mar 2017 18:29:00 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12919#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12919#comment:2</guid> <description> <p> Hi Joaquin, </p> <p> I can email you private details about the data, most of the strings are concatenations of <a class="missing wiki">UniProt</a> identifiers, a residue, and a protein position (of the form "P46406:C15", or "P46406:C15-P46406:C230", and as the data has not yet been published, I would rather not provide it on a public mailing list. </p> <p> The hash function used is boost::hash (the default hash is), and I have noticed that changing the hash function (std::hash does not cause an issue), or slightly tweaking the input data (such as removing the ":" in the identifiers), will make a given test-case that normally overruns the container size on a rehash to run normally. </p> <p> Just for the full, public bug tracker, I am using the multi_index characteristic of the container, the primary indexer is a hashed struct using boost::hash_combine, which includes an atypical data structure (a short, immutable, ordered set of pointers), and I have confirmed in all working cases the hash function is unique (there is not a single collision, and bucket loads are typically low). </p> <p> One other thing is that my proposed patch also does not fix infinite iteration when I was attempting to calculate the bucket size of the hashed_non_unique index, so my patch seems to be woefully insufficient, but I am unsure how to continue. </p> <p> I can provide a working test case privately via email. </p> <p> <strong>Rudimentary Code Snippet</strong><br /> </p> <p> Note: This snippet is missing includes, some template specializations, and a few other things. It's meant as a general idea of the model, not as working code. </p> <div class="wikipage" style="font-size: 80%"><p> Code highlighting: </p> <div class="wiki-code"><div class="code"><pre> <span class="c1">// this is identical to boost hash_combine_impl, just exported here</span> <span class="kr">inline</span> <span class="kt">void</span> <span class="nf">hash_combine_impl</span><span class="p">(</span><span class="kt">size_t</span><span class="o">&amp;</span> <span class="n">seed</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">value</span><span class="p">)</span> <span class="p">{</span> <span class="n">seed</span> <span class="o">^=</span> <span class="n">value</span> <span class="o">+</span> <span class="mh">0x9e3779b9</span> <span class="o">+</span> <span class="p">(</span><span class="n">seed</span><span class="o">&lt;&lt;</span><span class="mi">6</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="n">seed</span><span class="o">&gt;&gt;</span><span class="mi">2</span><span class="p">);</span> <span class="p">}</span> <span class="c1">// this uses the same magic numbers as Python&#39;s frozenset hash, </span> <span class="c1">// for immutable set hashing</span> <span class="k">struct</span> <span class="n">set_hash</span> <span class="p">{</span> <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="kt">size_t</span> <span class="k">operator</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span> <span class="o">&amp;</span><span class="n">t</span><span class="p">)</span> <span class="p">{</span> <span class="kt">size_t</span> <span class="n">h</span> <span class="o">=</span> <span class="mi">1927868237</span> <span class="o">*</span> <span class="p">(</span><span class="n">t</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="kt">size_t</span> <span class="n">i</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&amp;</span><span class="nl">v</span><span class="p">:</span> <span class="n">t</span><span class="p">)</span> <span class="p">{</span> <span class="n">i</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">hash</span><span class="o">&lt;</span><span class="k">decltype</span><span class="p">(</span><span class="n">v</span><span class="p">)</span><span class="o">&gt;</span><span class="p">()(</span><span class="n">v</span><span class="p">);</span> <span class="n">h</span> <span class="o">^=</span> <span class="p">(</span><span class="n">i</span> <span class="o">^</span> <span class="p">(</span><span class="n">i</span> <span class="o">&lt;&lt;</span> <span class="mi">16</span><span class="p">)</span> <span class="o">^</span> <span class="mi">89869747UL</span><span class="p">)</span> <span class="o">*</span> <span class="mi">3644798167UL</span><span class="p">;</span> <span class="p">}</span> <span class="n">h</span> <span class="o">=</span> <span class="n">h</span> <span class="o">*</span> <span class="mi">69069U</span> <span class="o">+</span> <span class="mi">907133923UL</span><span class="p">;</span> <span class="k">return</span> <span class="n">h</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="k">struct</span> <span class="n">my_item</span> <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">set</span><span class="o">&lt;</span><span class="kt">uintptr_t</span><span class="o">&gt;</span> <span class="n">pointers</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">set</span><span class="o">&lt;</span><span class="kt">uint32_t</span><span class="o">&gt;</span> <span class="n">positions</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">value</span><span class="p">;</span> <span class="p">};</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">my_item</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">my_item</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">)</span> <span class="p">{</span> <span class="k">auto</span> <span class="n">l</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">tie</span><span class="p">(</span><span class="n">lhs</span><span class="p">.</span><span class="n">pointers</span><span class="p">,</span> <span class="n">lhs</span><span class="p">.</span><span class="n">positions</span><span class="p">,</span> <span class="n">lhs</span><span class="p">.</span><span class="n">value</span><span class="p">);</span> <span class="k">auto</span> <span class="n">r</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">tie</span><span class="p">(</span><span class="n">rhs</span><span class="p">.</span><span class="n">pointers</span><span class="p">,</span> <span class="n">rhs</span><span class="p">.</span><span class="n">positions</span><span class="p">,</span> <span class="n">rhs</span><span class="p">.</span><span class="n">value</span><span class="p">);</span> <span class="k">return</span> <span class="n">l</span> <span class="o">==</span> <span class="n">r</span><span class="p">;</span> <span class="p">}</span> <span class="k">struct</span> <span class="n">my_item_hash</span> <span class="p">{</span> <span class="kt">size_t</span> <span class="k">operator</span><span class="p">(</span><span class="k">const</span> <span class="n">my_item</span> <span class="o">&amp;</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span> <span class="kt">size_t</span> <span class="n">seed</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">hash_combine_impl</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">set_hash</span><span class="p">()(</span><span class="n">i</span><span class="p">.</span><span class="n">pointers</span><span class="p">));</span> <span class="n">hash_combine_impl</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">set_hash</span><span class="p">()(</span><span class="n">i</span><span class="p">.</span><span class="n">positions</span><span class="p">));</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">i</span><span class="p">.</span><span class="n">value</span><span class="p">);</span> <span class="k">return</span> <span class="n">seed</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="k">struct</span> <span class="n">my_struct</span> <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">set</span><span class="o">&lt;</span><span class="n">my_item</span><span class="p">,</span> <span class="n">my_item_hash</span><span class="o">&gt;</span> <span class="n">set</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">string</span><span class="p">;</span> <span class="kt">uint32_t</span> <span class="n">count</span><span class="p">;</span> <span class="p">};</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">my_struct</span> <span class="o">&amp;</span><span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">my_struct</span> <span class="o">&amp;</span><span class="n">rhs</span><span class="p">)</span> <span class="p">{</span> <span class="k">auto</span> <span class="n">l</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">tie</span><span class="p">(</span><span class="n">lhs</span><span class="p">.</span><span class="n">set</span><span class="p">,</span> <span class="n">lhs</span><span class="p">.</span><span class="n">string</span><span class="p">,</span> <span class="n">lhs</span><span class="p">.</span><span class="n">count</span><span class="p">);</span> <span class="k">auto</span> <span class="n">r</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">tie</span><span class="p">(</span><span class="n">rhs</span><span class="p">.</span><span class="n">set</span><span class="p">,</span> <span class="n">rhs</span><span class="p">.</span><span class="n">string</span><span class="p">,</span> <span class="n">rhs</span><span class="p">.</span><span class="n">count</span><span class="p">);</span> <span class="k">return</span> <span class="n">l</span> <span class="o">==</span> <span class="n">r</span><span class="p">;</span> <span class="p">}</span> <span class="k">struct</span> <span class="n">my_struct_hash</span> <span class="p">{</span> <span class="kt">size_t</span> <span class="k">operator</span><span class="p">(</span><span class="k">const</span> <span class="n">my_struct</span> <span class="o">&amp;</span><span class="n">s</span><span class="p">)</span> <span class="p">{</span> <span class="kt">size_t</span> <span class="n">seed</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// these following lines are identical to boost::hash_combine_impl</span> <span class="n">hash_combine_impl</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">set_hash</span><span class="p">()(</span><span class="n">s</span><span class="p">.</span><span class="n">set</span><span class="p">));</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">s</span><span class="p">.</span><span class="n">string</span><span class="p">);</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash_combine</span><span class="p">(</span><span class="n">seed</span><span class="p">,</span> <span class="n">s</span><span class="p">.</span><span class="n">count</span><span class="p">);</span> <span class="k">return</span> <span class="n">seed</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="k">typedef</span> <span class="n">boost</span><span class="o">::</span><span class="n">multi_index_container</span><span class="o">&lt;</span> <span class="n">my_struct</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">multi_index</span><span class="o">::</span><span class="n">indexed_by</span><span class="o">&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">multi_index</span><span class="o">::</span><span class="n">hashed_unique</span><span class="o">&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">multi_index</span><span class="o">::</span><span class="n">identity</span><span class="o">&lt;</span><span class="n">my_struct</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">my_struct_hash</span> <span class="o">&gt;</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">multi_index</span><span class="o">::</span><span class="n">hashed_non_unique</span><span class="o">&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">multi_index</span><span class="o">::</span><span class="n">tag</span><span class="o">&lt;</span><span class="n">tags</span><span class="o">::</span><span class="n">my_tag</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">multi_index</span><span class="o">::</span><span class="n">const_mem_fun</span><span class="o">&lt;</span><span class="n">my_struct</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">my_struct</span><span class="o">::</span><span class="n">linkage</span><span class="o">&gt;</span> <span class="o">&gt;</span> <span class="o">&gt;</span> <span class="o">&gt;</span> <span class="n">my_struct_memo</span><span class="p">;</span> </pre></div></div></div><p> Best, Alex </p> </description> <category>Ticket</category> </item> <item> <author>Alex Huszagh <ahuszagh@…></author> <pubDate>Tue, 21 Mar 2017 18:33:41 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12919#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12919#comment:3</guid> <description> <p> Sorry, I am realizing I cannot edit comments, I forgot a few small items in my code snippet: </p> <div class="wikipage" style="font-size: 80%"><p> Code highlighting: </p> <div class="wiki-code"><div class="code"><pre><span class="k">namespace</span> <span class="n">tags</span> <span class="p">{</span> <span class="k">struct</span> <span class="n">my_tag</span> <span class="p">{};</span> <span class="p">}</span> <span class="c1">// tags</span> <span class="c1">// skip many lines</span> <span class="c1">// ...</span> <span class="k">struct</span> <span class="n">my_struct</span> <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">set</span><span class="o">&lt;</span><span class="n">my_item</span><span class="p">,</span> <span class="n">my_item_hash</span><span class="o">&gt;</span> <span class="n">set</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">string</span><span class="p">;</span> <span class="kt">uint32_t</span> <span class="n">count</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">linkage</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span> <span class="p">};</span> <span class="c1">// skip many lines</span> <span class="c1">// ...</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">my_struct</span><span class="o">::</span><span class="n">linkage</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="c1">// implementation not shown</span> <span class="p">}</span> </pre></div></div></div> </description> <category>Ticket</category> </item> <item> <author>Alex Huszagh <ahuszagh@…></author> <pubDate>Tue, 21 Mar 2017 20:31:50 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12919#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12919#comment:4</guid> <description> <p> For some reason, if I use only std::hash, or only boost::hash for primitives, everything works fine. This might be some weird magic in magic numbers. I will be running a lot more test cases (and fuzz with random data) to see if I can actually create a working example, if not, please close this. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Joaquín M López Muñoz</dc:creator> <pubDate>Wed, 22 Mar 2017 10:14:07 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12919#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12919#comment:5</guid> <description> <pre class="wiki">std::set&lt;my_item, my_item_hash&gt; set; </pre><p> This looks very weird to me: <code>std::set</code> expects a strict weak order-inducing binary predicate as its second template parameter, yet you are passing a hash functor. How can this even compile? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Joaquín M López Muñoz</dc:creator> <pubDate>Tue, 28 Mar 2017 07:14:01 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/12919#comment:6 https://svn.boost.org/trac10/ticket/12919#comment:6 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> Closing due to lack of further feedback from OP. </p> Ticket