class derivation in boost.python v2. Was Re: [C++-sig] LifetimeofPython object for a pointer argument
David Abrahams
david.abrahams at rcn.com
Tue Feb 19 14:44:39 CET 2002
----- Original Message -----
From: "Min Xu" <minxu at sci.ccny.cuny.edu>
> Thanks.
>
> Your fix is great. It now reports the uninitialized base class though
> with the name prefixed by a digit such as 8geometry. -:)
Are you volunteering to follow up on the attached message to get better
error reports from GCC?
----------
There are a few places where error reporting in Boost.Python depends on
being able to show users a reasonable representation of a C++ type name.
Currently, we use typeid(x).name() to get the name. Most compilers produce a
good result, however g++ does not. I just ran a small experiment to see if
the type encoding scheme used by G++ could easily be deciphered, and it
appears that it can. If we want to improve error reporting with G++, it
should be relatively easy.
The enclosed program indicates the following encoding information:
v void
c char
h unsigned char
a signed char
i int
j unsigned int
i signed int
s short
l long
x long long
f float
d double
e long double
P% %*
R% %&
K% % const
V% %volatile
A##_% %[##] an array of ## %s, e.g. A4_c => char[4]
##... A name of length ##, e.g. 3foo => foo
N%1%2...%nE %1::%2::...%n A qualified name, e.g. N3foo3barE => foo::bar
F%1%2...%nE %1 ()(%2,...%n) A function, e.g. PFicE => int (*)(char)
S_ Back-reference to the first name spelled ##..., e.g. PF3fooS_E => foo
(*)(foo)
S##_ Back-reference to the ##+2'th name, e.g. PF3foo3barS0_E => foo
(*)(bar,bar)
Note that back-references increase the count, so:
PF3fooS_3barS1_E => foo (*)(foo, bar, bar)
not S0_ --------------^^^
M%1%2 %2 (%1::*) Member pointer, e.g. M3fooi => int (foo::*)
M3fooFvvE => void (foo::*)(void)
%1I%2%3...%nE %1<%2,%3...%n> class template, e.g. 3fooIilE => foo<int,long>
L%## ## non-type template parameter of type L and value ##, e.g.
3fooILi42E => foo<42>, where 42 is an int
I got stumped at function non-type template parameters:
3fooIXadL_Z1fvEEE => foo<f>, with template<void (*)()> class foo / void f()
^^^^^^^^^^^
3fooIXadsr6foobarNS0_1fEvEE => foo<foobar::f>,
^^^^^^^^^^^^^^^^^^^^^
with template<void (foobar::*)()> class foo, void foobar::f()
---------
Anyway, if someone would like to translate this information into code (and
complete the job for non-type template parameters, if possible), we could
easily have better error reporting for g++ users.
-Dave
-------------
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <typeinfo>
#include <cstdio>
#include <utility>
#define DUMP(type) std::printf("%s %s\n", typeid(type).name(), #type)
namespace foo
{
namespace young
{
struct egg {};
}
struct bar {};
enum baz {};
}
struct foobar {
struct baz {};
void f();
};
template <class T, class U, long, int> struct Template {};
struct x {};
struct xx {};
struct xxx {};
struct xxxx {};
void f();
template <void (*)()> struct TemplateTwo {};
template <void (foobar::*)()> struct TemplateThree {};
int main()
{
DUMP(char);
DUMP(char*);
DUMP(char const*);
DUMP(char const volatile*);
DUMP(char[20]);
DUMP(unsigned char);
DUMP(signed char);
DUMP(int);
DUMP(unsigned int);
DUMP(unsigned int*);
DUMP(unsigned int const*);
DUMP(unsigned int volatile*);
DUMP(unsigned int const volatile*);
DUMP(signed int);
DUMP(short);
DUMP(long);
DUMP(long long);
DUMP(float);
DUMP(double);
DUMP(long double);
DUMP(foobar);
DUMP(foobar::baz);
DUMP(foo::bar);
DUMP(foo::baz);
DUMP(foo::young::egg);
DUMP(x (*)(x));
DUMP(x (*)(xx,xx));
DUMP(x (*)(xx,xxx,xxx));
DUMP(x (*)(xx,xxx,xxxx,xxxx));
DUMP(void (*)());
DUMP(int (*)());
DUMP(int& (*)());
DUMP(void (*)(int));
DUMP(void (*)(int&));
DUMP(void (*)(int const&));
DUMP(void (*)(int const volatile&));
DUMP(void (*)(int,foobar));
DUMP(foo::baz (foobar::*)(int,foobar));
// work around macro issues
typedef Template<long,char*,42,99> template_foobar_3;
DUMP(template_foobar_3);
typedef std::pair<int,std::pair<long,char> > pair_int_pair_long_char;
DUMP(pair_int_pair_long_char);
typedef std::pair<foobar,std::pair<foobar,std::pair<foo::baz,foo::baz> >
> pair_foobar_pair_foobar_pair_foobaz_foobaz;
DUMP(pair_foobar_pair_foobar_pair_foobaz_foobaz);
typedef TemplateTwo<f> template_two_f;
DUMP(template_two_f);
typedef TemplateThree<&foobar::f> template_three_f;
DUMP(template_three_f);
}
More information about the Cplusplus-sig
mailing list