I have recently studied Intellisense in VS2008, as I'm developing a rather large C++ numerical linear algebra library where templates and such are used extensively. Intellisense stopped working shortly into the project and I sort of gave up, but now it became really annoying without it so I set to investigate. This is what I found out:
Assuming there is a file(s), containing code that "breaks" Intellisense,
- if header files that break Intellisense are in the project, but are not
#include
d, it still works in the rest of the files
- if they are included, but no type declared inside is used, it still works
- if they are included and a type declared inside is used, it might still work a bit (no Intellisense for members, no Intellisense after occurrence of given type, but at least global names and argument info before)
- if Intellisense is broken in one .cpp file, it can still work in the others where the problematic code is not included or used (but i imagine if it crashes bad, it will get disabled for the whole project, although that did not happen to me)
- Intellisense seems to be updated after successful compilation (sometimes not before)
- putting broken code inside any of
#if 0
, /* .. */
or //
seems to put Intellisense at ease
From the C++ features I used, actually only a few break Intellisense:
- comparison with '>' or '>=' in template parameter (e.g.
static_assert<(size > 0)>
)
- not solved by using double parentheses (
static_assert<((size > 0))>
does not help)
- solved by using '<' or '<=' instead (
static_assert<0 < size>
works)
- solved by storing the value in enum and using that to specialize the template
- explicit function template specialization disables argument info (e.g.
function<type>(args)
)
- probably unable to solve (maybe wrap in a macro), but I can live with it being broken
- instantiation of template member type, such as
Matrix::MakeMatrixType<3, 3>::Result r;
- kind of hard to figure out exactly why this happens (likely because of use of Eigen)
- workaround by moving such code in a separate .cpp where IS won't work (not always possible)
It would seem that some of those problems are due to some "simplified" parsing, which is less strong than a proper C++ parser. With the above information at hand, a "reliable" method of making Intellisense work in an existing code:
- Set up an empty project (a console app), create Main.cpp with dummy
void main() {}
in it.
- Include one of your broken header files, and
math.h
- Build (it must compile, in order for Intellisense to update reliably)
- Test whether Intellisense is working by typing e.g.
sin(
and seeing if argument help pops up. Sometimes, this would work, but member help wouldn't - so try that as well.
- Make an instance of something in the header file, build, see if that manages to kill IS.
- Remove code from the culprit file and go to step 3
- After finding and fixing problematic code, put back code removed in step 5, try again
- After making a whole class work well, make an instance of the next class, and so on ...
I found it easy this way to pinpoint locations of code that made problems (I realize that this might be unfeasible for really large projects, in my case only a single file out of 97 made problems). Note that 'Build' here refers to compiling, the linking stage does not need to finish, so unresolved externals are ok, the IS should update regardless.
Another method of updating IS (other than building) is to save everything, close workspace, delete .ncb file and reopen it. Then wait for 'Updating Intellisense ... (N)' to disappear from the status bar (N counts towards zero, if it doesn't go all the way, it kind of shows progress where problems occurred). I found this rather tedious.