When an error message is worth a thousand words

Posted on by Anastasia Kazakova

ReSharper C++ is currently running its Early Access Program for v2018.3, which already has a few important enhancements to offer:

  • C++/CLI support has been improved with several new context and generate actions for C++/CLI code.
  • Solutions are loaded a lot faster, especially those that use the Unreal Engine. The main catch is that ReSharper C++ only parses non-engine projects during the initial indexing; the engine files are indexed in the background later.
  • Predefined naming schemes for common C++ code standards were introduced.
  • Refactorings, code generation, formatting, and other areas have been enhanced in various ways.

Among these improved areas, there’s one we’d like to talk about in more detail. The error annotator in ReSharper C++. These improvements are available in the recently published 2018.3 EAP 6 build. Let’s see what it’s all about!

When the overload resolution fails in C++, you often get error messages that don’t tell you the exact cause of the problem. Messages like ‘Substitution failed’, ‘Couldn’t infer substitution’, or ‘no instance of function matches the argument list’ are of little help unless additional details are provided:

An error message like that does give you some hints, suggesting that probably the argument used in your template function call is wrong. Still, it doesn’t say which specific requirements were not satisfied. Figuring things out gets even more complicated if the template code is located far from where the error occurs.

For example, in the code sample above, it would be much easier to pinpoint the problem if the error explicitly said that there was no type named inner_type in struct Y. This is actually what compilers like clang (7.0) or GCC (8.2), and now ReSharper C++ will tell you:

Another example is when the substitution fails because a member is missing:

Starting with the latest EAP build, ReSharper C++ will now warn you about this pattern, pointing out the particular ill-formed expression that uses the missing member in the template.

Better error messages for enable_if

ReSharper C++ will show a similarly useful error message when enable_if is used to conditionally remove functions from the overload resolution set. Knowing which specific condition is not satisfied, you can debug your code more easily.

In the example below, ReSharper C++ will understand that the is_integral requirement fails (instead of just saying that ‘No instance of the overloaded function matches the list’):

Another example of this kind is when the is_default_constructible condition is not satisfied:

In another interesting case, Visual Studio 15.8 extended std::pair with one more default constructor (an explicit one). Well, ReSharper C++ checks all the candidates and tells you in every why they don’t fit:

As you can see from the screenshot above, other overloads are also listed in addition to the candidates considered.

Finally, here’s where we think ReSharper C++ does an even better job than all the three major compilers (Microsoft Visual C++, Clang and GCC):

For this piece of code, MSVC provides ‘no instance of function template “do_stuff” matches the argument list, argument types are: (int, int)’ message, while Clang shows a more reasonable error, namely ‘requirement ‘std::conjunction_v, std::is_floating_point >’ was not satisfied [with T = int, U = int]’. But ReSharper C++ does it one better: it shows the argument that broke the substitution ((int)2) and the condition that was not fulfilled (is_floating_point::value)!

Check out the latest ReSharper C++ 2018.3 EAP build and let us know if this enhanced error annotator helps you resolve substitution failures in your code! Your feedback will be greatly appreciated, as always.

Your ReSharper C++ Team


Subscribe for updates