8.2. Using Tools for Diagnostic AnalysisThough their efforts sometimes backfire, compiler vendors are clearly going out of their way to address the problem of unreadable template error messages. That said, even the best error message formats can still leave a lot to be desired when a bug bites you from deep within a nested template instantiation. Fortunately, software tools can be an immense help, if you follow three suggestions. 8.2.1. Get a Second OpinionOur first recommendation is to keep a few different compilers on hand, just for debugging purposes. If one compiler emits an inscutable error message, another one will likely do better. When something goes wrong, a compiler may guess at what you meant in order to report the mistake, and it often pays to have several different guesses. Also, many compilers have intrinsic deficiencies when it comes to error reporting. For example, though it is an otherwise excellent compilerand one of the very fastest in our timing testsMetrowerks CodeWarrior Pro 9 often fails to output filenames and line numbers for each "frame" of its instantiation backtrace, which can make the offending source code hard to find. If you need to trace the source of the error, you may want to try a different toolset.
8.2.2. Use Navigational AidsFor traversing instantiation stack backtraces, it's crucial to have an environment that helps you to see the source line associated with an error message. If you're one of those people who usually compiles from a command shell, you may want to issue those commands from within some kind of integrated development environment (IDE), just to avoid having to manually open files in an editor and look up line numbers. Many IDEs allow a variety of toolsets to be plugged in, but for debugging metaprograms it's important that the IDE can conveniently step between messages in the various compilers' diagnostic formats. Emacs, for example, uses an extensible set of regular expressions to extract filenames and line numbers from error messages, so it can be tuned to work with any number of compilers. 8.2.3. Clean Up the LandscapeFinally, we suggest the use of a post-processing filter such as TextFilt (http://textfilt.sourceforge.net) or STLFilt (http://www.bdsoft.com/tools/stlfilt.html). Both of these filters were originally designed to help programmers make sense of the types in their STL error messages. Their most basic features include the automatic elision of default arguments from specializations of known templates, and typedef substitution for std::string and std::wstring. For example, TextFilt transforms the following mess: example.cc:21: conversion from 'double' to non-scalar type 'map<vector<basic_string<char, string_char_traits<char>, __default_alloc_template<true, 0> >, allocator<basic_string<char, string_char_traits<char>, __default_alloc_template<true, 0> > > >, set<basic_string<char, string_char_traits<char>, _ _default_alloc_template<true, 0> >, less<basic_string<char, string_char_traits<char>, __default_alloc_template<true, 0> > >, allocator<basic_string<char, string_char_traits<char>, __default_alloc_template<true, 0> > > >, less<vector<basic_string<char, string_char_traits<char>, __default_alloc_template<true, 0> >, allocator<basic_string<char, string_char_traits<char>, __default_alloc_template<true, 0> > > > >, allocator<set<basic_string<char, string_char_traits<char>, __default_alloc_template<true, 0> >, less<basic_string<char, string_char_traits<char>, _ _default_alloc_template<true, 0> > >, allocator<basic_string<char, string_char_traits<char>, __default_alloc_template<true, 0> > > > > >' requested into the much more readable: example.cc:21: conversion from 'double' to non-scalar type 'map<vector<string>,set<string>>' requested TextFilt is interesting because it is easily customizable; you can add special handling for your own types by writing "rulesets," which are simple sets of regular expression-based transformations. STLFilt is not so easily customized (unless you enjoy hacking Perl), but it includes several command line options with which you can tune how much information you see. We find these two indispensable for template metaprogramming.
Any tool can obscure a diagnostic by applying too much filtering, and STLFilt is no exception, so we encourage you to review the command line options at http://www.bdsoft.com/tools/stlfilt-opts.html and choose carefully. Fortunately, since these are external tools, you can always fall back on direct inspection of raw diagnostics. |