|
Boost : |
Subject: [boost] TMP error messages [ was Re: New libraries implementing C++11 features in C++03 ]
From: Joel de Guzman (joel_at_[hidden])
Date: 2011-11-24 19:34:56
On 11/25/2011 3:10 AM, Daniel James wrote:
> On 24 November 2011 13:35, Dean Michael Berris <mikhailberis_at_[hidden]> wrote:
>>
>> Why are people blaming the libraries for horrible error messages when
>> it's compilers that spew these error messages?
>
> They just don't want to use a library which has horrible error
> messages. It doesn't matter if it's the library's fault or the
> compiler's fault. Blame has nothing to do with it.
Those are very good points, Daniel. So is this, from Nathan:
> The problem is that errors point to code that is deep within the library's
> implementation, or worse, the implementations of helper libraries used
> by the library. To understand the error, the user has to look at the
> library's implementation. The user shouldn't have to do that -
> understanding the implementation of a library should not be a
> prerequisite for using it.
>
> If you have any specific suggestions about what compilers could do to turn
> these errors from deep within the library implementation, into errors
> that do not require knowing anything about the library implementation,
> I would like to hear it, and I'm sure so would compiler writers.
>
> Otherwise, you have to accept that library writers face a trade-off
> between the user-friendliness of error messages, and the expressiveness,
> terseness, and power obtained by extensive use of advanced techniques
> such as template metaprogramming. There is no one right answer to
> this tradeoff, and it is good for users to have different alternatives
> available to them.
It's not that we TMP/ET advocates are ignorant about it. There
have been efforts to fix or at least alleviate this problem. Yet,
it's still not enough to satisfy everyone. Eric Niebler noted
that it is a bug if a library spews error messages and that the
one encountering such problems should report it as a bug for the
author to fix. We've done that in Spirit by detecting invalid
expressions as early as possible with a static-assert:
template <typename Auto, typename Expr>
static void define(rule& lhs, Expr const& expr, mpl::false_)
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
}
The goal is to provide better diagnostics for the user. The code is
isolated (notice that this branch of code calls nothing else in
order to minimize the error trace).
Brent Spillner triggered this static-assert:
> But that's nothing; if you omit the '>>' from the expression or term
> definition you get the 33 kilochar beauty copied at the bottom of this
> email.
With MSVC, you see the error up front:
C:\dev\boost\boost/spirit/home/qi/nonterminal/rule.hpp(176) : error
C2664: 'boost::mpl::assertion_failed' : cannot convert parameter 1 from
'boost::mpl::failed ************(__thiscall
boost::spirit::qi::rule<Iterator,T1,T2,T3,T4>::define::error_invalid_
expression::* ***********)(Expr)' to 'boost::mpl::assert<false>::type'
Plus some more extra error trace after which leads you
to the erroneous Spirit expression.
G++ is worse. It spews 4 long lines of trace before the actual
static-assert. You'll have to do a textual search for "error"
to get to the actual error. You might think that 4 lines is
not that long, but these 4 lines contain complex ET types that
the casual user need not know about.
Right now, we are using BOOST_MPL_ASSERT_MSG. I switched to
c++11 static_assert and now I get a better error message
in MSVC:
C:\dev\boost\boost/spirit/home/qi/nonterminal/rule.hpp(179) : error
C2338: Invalid Expression
C:\dev\boost\boost/spirit/home/qi/nonterminal/rule.hpp(223) : see
reference to ...
plus some more extra error trace after.
With g++, I get:
C:\dev\boost/boost/spirit/home/qi/nonterminal/rule.hpp:179:13: error:
static assertion failed: "Invalid Expression"
Which looks good, but without any trailing error trace, there's
no way to follow the trail to where the actual error is. (I think
that's a g++ bug! If you care about g++, they should be informed
about this problem.)
Sooo... despite our valiant efforts, the current state of affairs
is still not good enough. People scared with error messages are
still turned off.
Now. What else can we do about it? Here's an idea. I'd like to
hear yours.
Presentation:
The error trace is very noisy! It contains lots of types with
full qualifications. E.g.
Expr =
boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,
boost::proto::argsns_::list2<const
boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript
It might be good to present that in a GUI where the types are
collapsed by default. Qualifications in a trace can also be
optionally collapsed.
With this, the user will see only this, for example:
[+] rule.hpp(179) : error C2338: Invalid Expression
[+] rule.hpp(223) : see reference to function template instantiation [+]
with[+]
[+] calc3.cpp(54) : see reference to function template instantiation [+]
with[+]
[+] calc3.cpp(43) : while compiling class template member function [+]
with[+]
[+] calc3.cpp(90) : see reference to class template instantiation [+]
with[+]
Clicking one of the [+] will reveal further information, hierarchically.
It is possible to write a parser for the common compilers (MSVC and g++)
and have it generate the data in HTML with some javascript for
collapsing the data, or maybe just XML since text editors can collapse
XML nodes already.
I care about TMP in general and especially ET. I'd like to make the
situation better, lest we will have more anti-TMP sentiment. I'm sure
many people here care too. It's so utterly frustrating to see people
avoid TMP libraries because of this prevalent problem. If there
are any more nice ideas (hey this is Boost and we are full of wonderful
ideas!), please share them.
Regards,
-- Joel de Guzman http://www.boostpro.com http://boost-spirit.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk