Hello, my name is Raman Sharma, and I am a Program Manager on the VC++ team. Through this blog post, I wish to highlight some changes we have made to an important feature in the C++ IDE, called “Find all References”. As most of you would know, this feature is used to search for references to any element of your code (classes, class members, functions etc.), inside the entire solution. In Visual Studio 2010, we have made some changes to this feature to provide more flexibility.
Let’s look at these changes through an example. Let’s say you have the following piece of code:
Figure 1: Sample Code
In Visual Studio 2008, if you invoke “Find all References” on the member function printArea of class Circle as in:
Figure 2: Invoke Find all References
You will see the results showing line numbers 7, 20 & 26 as below:
Figure 3: Results in VS 2008
It is to be noted that the results window does not list all the places the word “printArea” appears. It only lists specifically the places where printArea means the “member function printArea of class Circle” (on which Find all References was invoked). The point is that this is in some sense a compiler-verified-search (I just coined that term but the concept is correctJ) wherein you will get exactly the C++ symbol you searched for.
In Visual Studio 2010 we have effectively created two modes of search: one that focuses on speed and the other that focuses on accuracy. Needless to say, you can specify the default mode through options and we will remember that setting. More on that later in this post.
If you perform the same operation as described above in VS 2010, by default you will get the following results:
Figure 4: Default results in VS 2010
Please note that this time around, the results window does list all the places the word “printArea” appears (including the comments!). Why? Because we wanted to provide the user with an option to search without invoking the compiler. Needless to say, this option will speed up the search significantly, especially for large projects with a lot of hits.
It’s worth mentioning that this search is unlike just searching for some text in the entire solution. This is because for this search, the C++ IDE uses an index to narrow the list of files to search. So it doesn’t look through all the files in the solution. The outcome is significantly better performance than just “Find in Files” (or grep), especially for large solutions.
However, we understand that there can be instances where you want to reduce the ambiguity by filtering the results further. This means you want better accuracy. If you search for a member function of a class, you only want references to that member function of that class. This is even if there are other classes with same named members or other overloads for this function within the same class. To do this, right-click on the results in the results window and invoke “Resolve Results”:
Figure 5: Invoke Resolve Results
“Resolving results” uses the compiler to actually verify/confirm the entries and removes references that don’t precisely match. You will be presented with the following results which contain only exact references to Circle::printArea:
Figure 6: Resolved results in VS 2010
If you are feeling more adventurous, there is another part of the accuracy mode which is like asking the following question to the compiler: “Filter out as many extraneous results as you can, and for those you are not sure about, show them anyway”. The reason you would want to ask that question is if you want comments, code in different macro states etc. to be included in the search results.
The way to ask this question is to simply right-click on the resolved results in the window and to uncheck “Hide Unconfirmed”:
Figure 7: Uncheck "Hide Unconfirmed"
Doing this will make sure that search results will exclude only those results which the compiler has verified are definitely not references of Circle::printArea. Anything that the compiler verifies is correct and anything it is not sure about will be listed. The results will be as shown below:
Figure 8: Resolved and Unconfirmed results in VS 2010
Notice this time the results include the comments. It’s worth mentioning that this is the only mode that was supported by VS 2008
The default mode for search is the speed mode. This means, when you invoke Find-all-References, you will see all the places your search item appears. However as with everything else in Visual Studio, there is a way to change this default behavior. If you go to “Tools -> Options -> Text Editor-> C/C++ ->Advanced”, under References you will find two new options “Disable Resolving” and “Hide Unconfirmed”:
Figure 9: Options to set default search mode
By default the “Disable Resolving” flag is set to True (means Speed mode). Setting it to False would cause all results to be verified with the compiler (means Accuracy mode). Similarly the default value of “Hide Unconfirmed” flag is True. Setting it to False will ensure that search results will contain unconfirmed results in addition to the resolved results. The second flag makes sense only when the first flag is set to False. Also to be noted is that resolving/unresolving from the results window will not affect the values of these flags. These are global settings meant to specify default behavior.
Overall, we believe that these changes have introduced more flexibility enabling users to optimize their experience based on their own needs. We are excited about this change and hope you will like it.
But I'll definitely enable resolving option on the first use.
Wow, what a useless feature. The point of finding references is to FIND REFERENCES. If I wanted to do a global file search, there's a feature for that.
I can't believe you guys wasted your time doing something so unbelievably dumb. Good to know that your wasting your time on idiocy like this instead of fixing actual, genuine bugs. Warms my heart.
While I might prefer a different installation default, I vehemently disagree with Joe. Work on this was not a waste of time. Using the compiler to find references is not always best (for example, "find references" is often invoked while editing code, and said code probably doesn't compile)
This is a step backwards. While speed is nice, the fastest implementation is useless unless if it is not accurate. Finding references should... find actual (=accurate) references.
It may be too late to redesign this feature, but at the very least make Accurate the default value.
It's not a step backwards or a waste of time. Note that one of the three modes is MORE accurate than what was in 2008. Another is the same as 2008 and another is a "fast but dumb" mode.
You don't have to use the fast mode, you can use the more accurate mode if you want to. Maybe you don't like the defaults but it's definitely a step forward.
I think I'll probably stay with the old behavior. Find all references usually only takes a few seconds, which is fast enough. I just wish I didn't have to manually push the plus sign after clicking "Find all references".
Geez. Why on Earth can't you simply add 'Use indexing' checkbox in the 'Find in files' dialog instead? This is what your so-called fast mode does, it searches for plain text in text files.
Some remarks on the settings shown in Figure 9:
Why are you provoking double negation in the settings? I have to set Hide Confirmation to false to see everything and true to get a reduced view. This seems to be counter-intuitive. This is similar for all settings on this page: entering true to reduce functionality and false to extend functionality. You always have to look twice and think about.
Just a usability issue but it is so ubiquitous.
What about splitting results in to const/non-const references? Suppose I have a member 'mem1' with the wrong value being written to it. Then I could search for all non-const references to 'mem1'. This would filter out statements I'm uninterested in such as 'auto x = mem1' or cases where it's passed as a const reference function parameter, leaving only statements where 'mem1' is actually modified.
+1 for ashleg's suggestion
Also, I noticed that Reference Highlighting is broken (or non-existent) for C++ where selecting a symbol highlights the references. Any chance that'll make RTM?
I have to strongly agree with BongoVR about the negative settings labels; it just does not make sens and it counter-productive.
for example "Disable Database" should be "Enable Database"
does it goes a bit against the Vista user experience document (page 80).
"In general use positive phrasing..."
Looking forward to this actually being usable in VS2010. In current versions, it fails most of the time when looking up common function names, where there might be hundreds of classes with the same (but unrelated in a code sense) member function names.
It would be nice to see the results split into categories though. Definitions, declarations, calls and pointer references all get lumped together at the moment.
I agree with the choices, but the user interaction is hideously complex.
It is consistent with the design of Visual Studio - more and settings are accrued to avoid doing anything wrong.
However, every setting is a choice the software designers evaded - and loaded upon the user.
Do I really have to decide if I feel "adventurous" about finding references? Do I really have to decide between "fast index-based" and "slower file walk" search?
How many developers will just wonder why they find different references than their co-worker? How many developers will remember "there was some option related to that", but can't find it?
I don't want more flexibility, I don't want to "be enabled", I just want to find that reference.
I understand that it is a complicated feature, and your post shows clearly that you worked hard to get it right - and tried to weight all those tradeoffs that make such a feature so hard to get right for everyone.
But please also understand my point: for usability, to many options is bad.
also +1 for: separating access from (potential) assignment, avoiding double negatives.
Thanks for all the feedback.
@Joe: We understand the need to find the exact references which is why that capability is still there.
@pingpong: As mentioned in the post, the fast mode doesn't search for plain text in all text files. It does that in a much reduced set.
@BongoVR @Max: I would like to mention that there is a description text below which tells you what each option is meant for. But, your point is well taken. While we can't promise that change in this release, we will try to make it better next time.
@jschroedl: We have decided not to add highlight references for C++ this time. Again, this is definitely something of high interest even to us for the next version.
@peterchen: I am glad you understand this is not an easy feature to design or even change (considerng the existing usage habits). Which is why we decided to have all those options. For example, it's not uncommon for users to follow a Find-all-References operation by a Find-in-Files operation "just to be sure". This is despite our promise for accurate references. Now, you can choose what you want.