Boost logo

Boost :

From: Brian Parker (brianjparker_at_[hidden])
Date: 2002-04-04 08:50:30


Hi,

I agree that some kind of language support for simplifying compiler
diagnostics for library template code is essential for making C++
environments more user-friendly (and ideally some such scheme would be a
part of the next standard revision).

I haven't yet had a chance to download and test your approach against my own
library code, but I plan to do so in the near future.
I thought, though, that you might be interested in a related scheme I
implemented a while ago on the ECGS compiler (a GCC fork) which, whilst
being extremely simple, was remarkably effective on the code samples I
tested it with, and that may be complimentary to your current scheme.

The full details can be found at the thread-

http://groups.google.com/groups?hl=en&selm=78tp0a%242eg%241%40bunyip.cc.uq.edu.au&rnum=15

but the basic idea (in the final form) was an extension to the namespace
syntax to allow an optional text message for a namespace wrapping a library
e.g.
namespace boost::function "Boost Function library" {

If such a message was added then the compiler would not show the template
instantiation stack *within* such a namespace (the string label indicating
that this is library code) but, importantly, would show all of the
instantiation stack *outside* of the namespace which presumably is in the
user's own code, and would only display the general class of the compilation
error (e.g. "type conversion error", "operator++ not found" etc.) leaving
out details of types within the library code.

For example, in your original example, assuming that the Boost Function
library had a namespace declaration like-

"namespace boost::function "Boost Function library" {"

, then for the bogus code bogus code:

  class X {};
  int foo(X*);
  boost::function<int, float> f(&foo);

Instead of-

-----------------------------------------------------------------
../../../boost/function/function_template.hpp: In static member function
   `static R boost::detail::function::function_invoker1<FunctionPtr, R,
   T0>::invoke(boost::detail::function::any_pointer, T0) [with FunctionPtr =
   int (*)(X*), R = int, T0 = float]':
../../../boost/function/function_template.hpp:461: instantiated from `void
boost::function1<R, T0, Policy, Mixin, Allocator>::assign_to(FunctionPtr,
boost::detail::function::function_ptr_tag) [with FunctionPtr = int (*)(X*),
R
= int, T0 = float, Policy = boost::empty_function_policy, Mixin =
boost::empty_function_mixin, Allocator =
std::allocator<boost::function_base>]'
../../../boost/function/function_template.hpp:444: instantiated from `void
boost::function1<R, T0, Policy, Mixin, Allocator>::assign_to(Functor) [with
Functor = int (*)(X*), R = int, T0 = float, Policy =
boost::empty_function_policy, Mixin = boost::empty_function_mixin, Allocator
= std::allocator<boost::function_base>]'
../../../boost/function/function_template.hpp:278: instantiated from
`boost::function1<R, T0, Policy, Mixin, Allocator>::function1(Functor) [with
Functor = int (*)(X*), R = int, T0 = float, Policy =
boost::empty_function_policy, Mixin = boost::empty_function_mixin, Allocator
= std::allocator<boost::function_base>]'
../../../boost/function.hpp:475: instantiated from `boost::function<R, T1,
T2, T3, T4, T5, T6, T7, T8, T9, T10>::function(Functor) [with Functor = int
(*)(X*), R = int, T1 = float, T2 = boost::detail::function::unusable, T3 =
boost::detail::function::unusable, T4 = boost::detail::function::unusable,
T5
= boost::detail::function::unusable, T6 = boost::detail::function::unusable,
T7 = boost::detail::function::unusable, T8 =
boost::detail::function::unusable, T9 = boost::detail::function::unusable,
T10 = boost::detail::function::unusable]'
bad_error_eg.cpp:29: instantiated from here
../../../boost/function/function_template.hpp:81: cannot convert `float' to
`X*
   ' in argument passing
-----------------------------------------------------------------

one would get the message-
"
Error in using Boost Function library. Error was-
../../../boost/function/function_template.hpp:81: type conversion error on
argument passing
bad_error_eg.cpp:29: instantiated from here
"
(note that if the bogus code had itself been within some user's template
code then the instantiation stack shown would include all of the
"instantiated from"'s outside of boost::function.)

(of course, a compiler switch could disable this restricted message output
and show the full instantiation stack)

This is only slightly less perspicuous, IMO, than your current error message
of-

"
bad_error_eg.cpp:29: objects of type 'int (*)(X*)' cannot be invoked with
   Boost.Function argument types '(float)'
"

though I can see how your scheme could generally give much more focussed
error diagnostics.

Actually, in the hack I did to the ECGS compiler, for ease of implementation
I only added a #pragma
#pragma libinterface boost::function "Boost Function library"

instead of the preferred syntax

namespace boost::function "Boost Function library" {

In the newsgroup thread, I discussed a more complicated scheme of nested
#pragmas that could potentially give more specific error messages, but I
never got around to implementing it.

Anyway, some such scheme may be a useful compliment to your current
approach; one possible problem with the approach of having a template to
output compiler diagnostics is that it needs explicit checks to be added to
the library code, which may lead to excessive checks in some cases.

Cheers,
Brian Parker

_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk