Skip to content

Conversation

@StephanTLavavej
Copy link
Contributor

I'm the primary maintainer of Microsoft's C++ Standard Library implementation. The MSVC developers regularly build popular open-source projects, including yours, with development versions of the build tools in order to find and fix regressions in the compiler and libraries before they're released to the world. This also allows us to provide advance notice of breaking changes, which is the case here.

I'm working on removing our non-Standard <hash_map> implementation, which has been deprecated for many years, with microsoft/STL#5764. Your project has been defining the escape hatch macro which warned that "<hash_map> is deprecated and will be REMOVED." Fortunately, switching your code over to use the Standard container was simple enough for me to do it (even though I know very little about your codebase) and I was even able to fix a small mistake with iterator types.

Although we're building your project with VS 2026 and your README says that you're using VS 2017, these changes will be compatible with VS 2017, and will unblock future upgrades for you.

Hope this helps!

Commits

  • Include <unordered_map> instead of <hash_map>.
  • Use std::unordered_multimap instead of stdext::hash_multimap.
  • Fix: Use unordered_multimap::iterator instead of hash_map::iterator.
    • In ApiReader.cpp, ApiReader::clearAll() is iterating through apiList, which is multi.
    • In ApiReader.h, ApiReader::getScoredApi() should be declared as taking multi to match its definition in ApiReader.cpp, as it's taking iterators into apiList.
    • This was compiling despite the single/multi mismatch because in MSVC's implementation, for both legacy hash_map and Standard unordered_map, the containers have the same iterator types regardless of single/multi, but it's still a conformance issue and should be fixed.
  • Remove _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS.

In ApiReader.cpp, ApiReader::clearAll() is iterating through apiList, which is multi.

In ApiReader.h, ApiReader::getScoredApi() should be declared as taking multi to match its definition in ApiReader.cpp,
as it's taking iterators into apiList.

This was compiling despite the single/multi mismatch because in MSVC's implementation, for both legacy hash_map and
Standard unordered_map, the containers have the same iterator types regardless of single/multi, but it's still a conformance
issue and should be fixed.
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @StephanTLavavej, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request updates the project to use standard C++ containers (std::unordered_multimap) instead of deprecated Microsoft-specific stdext::hash_multimap and <hash_map>. This change ensures future compatibility with Visual Studio, fixes an iterator type mismatch, and removes a deprecation warning suppression macro.

Highlights

  • Overall Intent: This pull request aims to modernize the codebase by replacing the deprecated Microsoft-specific stdext::hash_multimap and <hash_map> with the standard C++ std::unordered_multimap and <unordered_map>. This change is proactive, initiated by a Microsoft C++ Standard Library maintainer, to ensure compatibility with future Visual Studio versions (e.g., VS 2026) and unblock future upgrades, while remaining compatible with the project's current VS 2017 setup. It also includes a fix for an iterator type mismatch.
  • Key Changes: The core changes involve updating container types from stdext::hash_multimap to std::unordered_multimap across relevant files, changing include directives from <hash_map> to <unordered_map>, and correcting iterator types in function signatures and loops. Additionally, the _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS preprocessor definition is removed from the project configuration files, as it is no longer needed.
  • Detailed Changes: 1. CAPE/Scylla/ApiReader.cpp: The ApiReader::apiList declaration is updated to std::unordered_multimap. Iterator types for getApiByVirtualAddress, getScoredApi, and the loop in clearAll() are changed from stdext::hash_multimap::iterator (or stdext::hash_map::iterator in one case) to std::unordered_multimap::iterator. This specifically addresses a conformance issue where clearAll() was iterating through a multi map using a hash_map iterator type.
  1. CAPE/Scylla/ApiReader.h: The include for <hash_map> is replaced with <unordered_map>. The apiList member is updated to static std::unordered_multimap<DWORD_PTR, ApiInfo *>. The getScoredApi function declaration is updated to use std::unordered_multimap<DWORD_PTR, ApiInfo *>::iterator for its parameter, aligning with its definition.
  2. CAPE/Scylla/ImportsHandling.h: The include for <hash_map> is replaced with <unordered_map>.
  3. capemon.vcxproj: The preprocessor definition _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS is removed from the ClCompile settings for all Debug and Release configurations (Win32 and x64), as the deprecated stdext::hash_map is no longer in use.
  • Reviewer Activity: No reviewer activity has been recorded yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an excellent pull request that modernizes the codebase by replacing the deprecated stdext::hash_multimap with the standard std::unordered_multimap. The changes are clean, and the fix for the iterator type mismatch is a great catch. I have a few minor suggestions to further improve the readability and maintainability of the updated code.

{
public:
static stdext::hash_multimap<DWORD_PTR, ApiInfo *> apiList; //api look up table
static std::unordered_multimap<DWORD_PTR, ApiInfo *> apiList; //api look up table
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To improve readability and maintainability, consider introducing a type alias for std::unordered_multimap<DWORD_PTR, ApiInfo *>. This makes the code less verbose and easier to change in the future if the container type needs to be updated again.

This alias can then be used throughout ApiReader.h and ApiReader.cpp where this long type is referenced (e.g., line 73 in this file, and lines 15, 693, 776, 1119 in ApiReader.cpp).

	using ApiList = std::unordered_multimap<DWORD_PTR, ApiInfo *>;
	static ApiList apiList; //api look up table

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a reasonable improvement, but I intentionally refrained from performing unrelated cleanups, beyond fixing the single/multi confusion.

ApiInfo * ApiReader::getApiByVirtualAddress(DWORD_PTR virtualAddress, bool * isSuspect)
{
stdext::hash_multimap<DWORD_PTR, ApiInfo *>::iterator it1, it2;
std::unordered_multimap<DWORD_PTR, ApiInfo *>::iterator it1, it2;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The iterator it2 is declared but never used within the getApiByVirtualAddress function. It should be removed to improve code clarity and avoid potential confusion.

	std::unordered_multimap<DWORD_PTR, ApiInfo *>::iterator it1;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirm that it2 is unused and should be removed (good bot, I didn't notice that). However, I am intentionally refraining from performing unrelated cleanups in this PR.

Comment on lines +1119 to 1122
for ( std::unordered_multimap<DWORD_PTR, ApiInfo *>::iterator it = apiList.begin(); it != apiList.end(); ++it )
{
delete it->second;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This traditional for loop can be modernized by using a C++11 range-based for loop. It's more concise and less error-prone.

	for (const auto& pair : apiList)
	{
		delete pair.second;
	}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this would be an improvement and was tempted to perform it, but intentionally refrained from unrelated cleanups in this PR (I even avoided using auto for the iterator type, since there may be a coding convention that I am unaware of).

@kevoreilly
Copy link
Owner

Hi Stephan, thanks for bringing this issue to my attention. I feel honoured that my beloved capemon would benefit from input from yourself and your team, but I probably don't need to point out that this project owes a lot to its heritage as I am sadly not skilled enough to have written all the code here!

The code in question is originally from Scylla by @NtQuery: https://github.com/NtQuery/Scylla which looks abandoned for more or less a decade. This incarnation may be the only survivor, and I am open to improving it wherever possible but lack skills when it comes to C++.

For that reason I will of course gratefully accept your changes but would equally be happy to implement any other improvements you can see!

@StephanTLavavej
Copy link
Contributor Author

Thank you! I have my hands full with being the only maintainer of MSVC's STL reviewing contributor PRs so I don't have other improvements to suggest (other than using range-for loops when possible, and auto for iterators otherwise).

@kevoreilly kevoreilly merged commit 5ca5ec7 into kevoreilly:capemon Oct 15, 2025
kevoreilly added a commit that referenced this pull request Oct 15, 2025
@kevoreilly
Copy link
Owner

I have now implemented all of Gemini's suggestions. Thanks again!

@StephanTLavavej StephanTLavavej deleted the unordered_map branch October 15, 2025 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants