Pyd: Wrapping too many functions in a class gives a compiler error

BCS BCS at pathlink.com
Fri Jul 6 13:00:54 PDT 2007


Kirk McDonald wrote:
> Simen Haugen wrote:
> 
>> I cannot wrap all the functions in my class without getting the 
>> compile error:
>> Error: identifier _D3pyd9func_wrap1172__T22app (...) is too long by x 
>> characters.
>>
>> And its several thousand characters too long...
>>
> [snip]
> 
>>  wrap_class!(
>>   NSD
>>   , Init!(void function(char[], char[]))
>>   , Def!(NSD.filter, "filter", Respondent[] function(char[]))
>>   , Def!(NSD.filter, "filterResps", Respondent[] function(char[], 
>> Respondent[]))
>>   , Def!(NSD.countOf, "countOf", double function(char[]))
>>   , Def!(NSD.countOf, "countOfResps", double function(char[], 
>> Respondent[]))
>>   , Def!(NSD.getQuestion)
>>   , Def!(NSD.getQuestionIds)
>>   , Def!(NSD.getRespondent)
>>   , Def!(NSD.numQuestions)
>>   , Def!(NSD.respondents)
>>   , Def!(NSD.writeasc)
>>   , Def!(NSD.writensd)
>>   , Def!(NSD.writesps)
>>   , Def!(NSD.writecsv)
>>   , Def!(NSD.clear)
>>   , Property!(NSD.questions)
>>  );
>> }
> 
> [snip]
> 
> Curses. This is one of those things I knew would be a problem, but 
> always just put off doing something about.
> 
> wrap_class is, of course, a template. It looks something like this:
> 
> void wrap_class(T, Params...)();
> 
> The problem with templates is that every template instantiated results 
> in a mangled identifier being created in the object file. Identifiers 
> have a maximum length, so when a big long one is created like this, it 
> runs headlong into that maximum length. That variadic Params parameter 
> is the perfect place to run into it, since each of the things you pass 
> to it are fairly long in themselves.
> 
> I always knew this would be an issue, but I never tried explicitly 
> testing for the maximum length.
> 
> Pyd's API wasn't always like this. It used to look like this:
> 
> wrapped_class!(Foo) f;
> f.def!(Foo.bar);
> f.def!(Foo.baz);
> finalize_class(f);
> 
> This neatly side-steps any problems with maxiumum symbol lengths. 
> However, by having all of the arguments in a tuple like the current API 
> does, they are all available at compile-time, meaning I can use them to 
> generate a subclass of T, and do some very fancy stuff with polymorphism.
> 
> Barring any changes to the language (such as macros or the compile-time 
> reflection mechanisms I outlined in an earlier post), I basically one 
> option for fixing this, which is to bring back the old API. This is not 
> an attractive option, since then Pyd would basically have two APIs 
> side-by-side. (If I ditch the current API, I lose the polymorphism stuff.)
> 
> This means that, when wrapping a big class, you'll either be able to 
> have all of its methods, or the fancy polymorphism stuff, but not both. 
> This annoys me, deeply.
> 
> In a perfect world, I'd have both of the following:
> 
> * Templates which do not generate symbols, if those symbols aren't 
> actually needed. (Or some way for the user to specify a template's 
> symbol is not needed.)
> 
> * The compile-time reflection stuff I've been talking about. With that, 
> you'd just need to say:
> 
> wrap_class!(Foo);
> 
> (Although cases such as overloaded functions would still have to be 
> covered somehow.)
> 
> That said, I will be looking into whether I can shorten those symbol 
> names. I'm going to be banging my head against this for the next few 
> days, I can tell.
> 


it seems that a mixed in template ( mixin foo!(lots.of.stuff) ) only 
generates symbols for the stuff on the inside. These however have access 
to the stuff in the outer templates args list. My dparse.d template uses 
this to side step the symbol length issue with long strings as arguments.

p.s. I haven't actually tested this in detail so I may be looking at 
something else and be totally wrong.



More information about the Digitalmars-d mailing list